home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-13 | 133.6 KB | 4,374 lines |
- Shadow.library Documentation
- Library Version 5.0
-
- By David Navas
- Updated: 13 Nov 1992
-
- Copyright © 1992 by David Navas
- All Rights Reserved
-
- NAME
- AddAttributes -- Create the attribute table for a class.
-
- SYNOPSIS
- result = AddAttributes( class, tags, num, offset )
- d0 a0 a1 d0 d1
-
- FUNCTION
- This function creates the array of Attribute structures that are
- described both by the tags and by the superclass of the passed
- class.
-
- This is a low-level function which is used by the provided
- Metas. You should not have to call this function yourself,
- however you can if for some reason you feel compelled to do
- so.
-
- Note that the array of Attributes, as stored in the class'
- AttributeTable, includes all of the attributes, both as described
- in the tags, AND as described in the superclass. If you're
- looking for an attribute description, you don't need to look at
- any superclass to find it.
-
- It is unfortunate that, unlike METHODs, attributes defined in the
- superclass have to copied to all subclasses. In reality, only
- the WATCHED attributes NEED to be copied, however this
- involves an increased level of complexity which has yet to be
- implemented, and so it remains -- 16bytes per attribute.... sigh.
-
- There are some benefits, however. Multiple inheritence of
- attributes is easy. It's unimplemented, but it's a hop-skip-jump
- away....
-
- After forming the AttibuteTable, the attributes are qsort'ed by the
- attribute name, for fast attribute lookup. Note that this is a
- sorting by the System String's address, not by the string's value.
- For more information about system Strings, see the UseString()
- function.
-
-
- INPUTS
- META class; - the new class for which to build an
- AttributeTable.
- Function returns NULL if NULL class is
- passed.
- ATTRIBUTE_TAG tags[]; - the (optional) new atributes to
- include.
- long num; - the number of additional attributes
- from the class' superClass -- as
- returned by PrepareAttrTags().
- ULONG offset; - the offset at which the next attribute
- will reside. This is usually the
- size of the class' superClass.
-
- OUTPUTS
- long result; - result code (should be a BOOL, oh well.)
-
- Specifies whether the AttributeTable was successfully built. NULL
- indicates an error.
-
- RESULT
- The specified class' AttributeTable is initialized.
-
- BUGS
- none known.
-
- NOTES
- Attributes are guaranteed to be arranged according to the order in
- which they are specified in the tags[]. This allows you to build
- a fixed structure over several attributes, or even over the whole
- object definition. [Internally this is done for all of the classes,
- with the exception of DIRECTOR_CLASS.]
- EG:
- The following:
- ATTR_1 struct MyAttr1
- ATTR_2 struct MyAttr2
- ATTR_3 struct MyAttr3
-
- Is basically the same as:
- ATTR_1 struct {
- struct MyAttr1
- struct MyAttr2
- struct MyAttr3
- };
-
- SEE ALSO
- PrepareAttrTags()
- CopyDefaultAttributes()
- FreeAttributes()
- FindAttribute()
- FindAttrDefn()
- UseString()
-
- NAME
- AddAutoResource -- Adds an automatically freed resource to a process.
-
- SYNOPSIS
- result = AddAutoResource( task, resource, key)
- d0 a0 d0 a1
-
- FUNCTION
- This function adds the specified resource to the optionally
- specified task (defaults to current task) using the specified
- key.
-
- These resources are kept on the PROCESS_CLASS' ATTR_RESOURCETREE,
- and are automatically freed (via a METH_REMOVE, and a
- DropObject()) whenever:
- a) The process receives a METH_REMOVE
- b) The process receives a METH_DESTROY
- c) The process receives a METH_PROC_DISASSOCIATE
- d) A program inside of RemoveCurrentProgram() receives a ^C
- e) The default thread-start function inside of SHADOW (after
- returning from the METH_PROC_HANDLER method) receives a ^C.
-
- It is important to note that the resource is TRANSFERRED to
- (swallowed by) the ATTR_RESOURCETREE. So you no longer own an
- object pointer to the resource you passed to AddAutoResource().
-
- If this is a problem you can do:
- AddAutoResource(NULL, UseObject(resource), MYNAME)
- .
- .
- <code referencing resource>
- .
- .
- DropObject(resource)
-
- <continue processing, no longer have pointer to resource>
- .
- .
-
- INPUTS
- OBJECT task; - The optional task object that performs
- the auto-tracking. If not specified,
- assumes current taskObject.
- OBJECT resource; - The object to auto-track.
- char *key; - The name of the resource. Resources
- without names (key == NULL) are stored
- by their addresses. Name addresses of
- 0-255 are reserved for priority freeing.
- Resources are freed in INCREASING
- key order. Obviously, you can't
- use AddAutoResource() to add a
- resource at priority zero, as then the
- resource would be added at the address
- of the resource (NULL == 0).
-
-
- OUTPUTS
- BOOL result; - result code
-
- Specifies whether the resource was added correctly. If it was not,
- the resource is sent a METH_REMOVE, is dropped, and a FALSE value
- is returned to indicate an error.
-
- If the resource was NULL, then this function returns FALSE
-
- Otherwise returns TRUE
-
- RESULT
- The resource is now auto-tracked by the indicated process.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- RemoveAutoResource()
- DropObject()
- UseObject()
-
- NAME
- AddClassWatcher -- Adds a watcher to the given class.
-
- SYNOPSIS
- result = AddClassWatcher( watchName, director, pri, name, class )
- d0 a0 a1 d2 d0 d1
-
- FUNCTION
- This function will add the director to the class' attribute's
- watching SList at the given priority with the given name.
-
- This is a low-level function. You should use the provided
- DIRECTOR_CLASS methods instead and ask specifically for a
- class watcher. Example is in browser.c -- GlobalDirector....
- Or see the inluded ShadowLibraryMethods.doc for more details
-
-
- INPUTS
- char *watchName; - the attribute name to watch
- OBJECT director; - the director to add to the attribute
- watching SList.
- long pri; - the priority to add the watcher as.
- char *name; - the name of the watcher.
- META class; - the class to add the watcher to.
-
-
- OUTPUTS
- BOOL result; - result code
-
- The result code is a boolean indicating the success or failure of
- the function call. A zero value indicates that an error occured.
-
-
- RESULT
- The director is added to the class' attribute's watch list.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- AddWatcherNode()
- RemoveWatcherNode()
- RemoveClassWatcher()
-
- NAME
- AddMethods -- initializes a class' method table
-
- SYNOPSIS
- result = AddMethods( class, tags )
- d0 a0 a1
-
- FUNCTION
- This function creates the array of MethodHandler structures that are
- described both by the tags.
-
- This is a low-level function which is used by the provided
- Metas. You should not have to call this function yourself,
- however you can if for some reason you feel compelled to do
- so.
-
- Note that the array of MethodHandlers, as stored in the class'
- MethodTable, includes only those methods described in the tags
- field. Unlike attributes, the superclass' methods are NOT
- copied down to the newly defined class.
-
- While creating the MethodHandlers, the passed procObject and
- defnObject are UseObject()'d, ensuring that the destination process
- and the defining process hang around until the class referencing the
- methods goes away.
-
- After forming the MethodTable, the methods are qsort'ed by the
- method name, for fast method lookup. Note that this is a
- sorting by the System String's address, not by the string's value.
-
-
- INPUTS
- META class; - required class to add the methods to.
- METHOD_TAG tags[]; - the (optional and NULL-terminated) array
- of MethodTag elements.
-
- OUTPUTS
- int result; - result code
-
- The result code is an integer indicating the success or failure of
- the function call. A zero value indicates that an error occured.
-
-
- RESULT
- The class' verbs field is initialized.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DSM() DoShadow() [ShadowLibFuncs.doc]
- InvalidateCache()
- SetMethodArgs()
- DestroyMethodTable()
- FindMethodHandle()
- BlockMethod()
- RemoveAllPatches()
- SetupMethodTags()
-
- NAME
- AddSListNode -- Adds a node to a prioritized singly linked list.
-
- SYNOPSIS
- result = AddSListNode( list, object, pri, name )
- d0 a0 a1 d0 d1
-
- FUNCTION
- This function adds an object into a singly linked list with the
- given name at the given priority (list is ordered by
- priority).
-
-
- INPUTS
- SList *list; - a pointer to the list to which to add
- the object.
- OBJECT object; - the object to add.
- long pri; - the priority
- char *name; - the name to add it as.
-
-
- OUTPUTS
- BOOL result; - result code
-
- The result code is an integer indicating the success or failure of
- the function call. A zero value indicates that an error occured.
-
- Lists of equal priorities are treated as LIFOs.
-
-
- RESULT
- The list has one more node on it -- the passed object.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- FindNodePriInSList() AddWatchedSListNode()
- RemoveSListNode() RemoveWatchedSListNode()
-
- NAME
- AddTreeNode -- adds an object into binary tree.
-
- SYNOPSIS
- result = AddTreeNode( bt, object, key)
- d0 a0 a1 d0
-
- FUNCTION
- This function will add the object into the binary tree sorted on
- the key provided.
-
- The object is Used() by the UseObject() call when successfully
- placed in the binary tree.
-
- Any number of objects may exist in any number of binary trees.
- There is no restriction on how many trees an object can be
- placed, nor in how many times an object can reside in a binary
- tree (as there is with Exec lists).
-
- In addition, unlike many AVLTree implementation, objects
- inserted with the same key are handled correctly.
-
-
- INPUTS
- AVLTREE *bt; - a pointer to the root of the binary tree.
- OBJECT object; - the object to add into the tree.
- ULONG key; - the key value to insert on.
-
- OUTPUTS
- BOOL result; - result code
-
- zero on failure. (Couldn't allocate binary node)
-
-
- RESULT
- Object is added into binary tree.
-
- BUGS
- NOne known.
-
- NOTES
- Uses AVL trees. Do not depend on order of insertion
- on duplicate keys. (Duplicate keys do work, though.)
-
- Remember that the keys are sorted unsigned, not signed.
-
- SEE ALSO
- UseObject()
-
- AddTreeStringNode() AddWatchedTreeNode()
- FindTreeNode() AddWatchedTreeStringNode()
- FreeTreeAllNodes() RemoveWatchedTreeNode()
- RecurseTree() RemoveWatchedTreeStringNode()
- RemoveTreeNode()
- RemoveTreeStringNode()
-
- NAME
- AddTreeStringNode -- add an object to an AVLTREE keyed on a string.
-
- SYNOPSIS
- result = AddTreeStringNode( bt, object, name )
- d0 a0 a1 d1
-
- FUNCTION
- This function will add the object into the binary tree sorted on
- the name provided.
-
- The object is Used by the UseObject() call when successfully placed
- in the binary tree.
-
- The name uses the UseString and DropString conventions
- for system strings. The address of that string then
- determines the order the binary tree is sorted in. It
- is NOT sorted by the string itself, sorry.
-
-
- INPUTS
- AVLTREE *bt; - a pointer to the root of the binary tree.
- OBJECT object; - the object to add into the tree.
- char *name; - the name to insert on.
-
- OUTPUTS
- BOOL result; - result code
-
- zero on failure. (Couldn't allocate binary node, or system string)
-
-
- RESULT
- The object is added into the binary tree sorted on the address of
- the system string that is uniquely created on the passed name.
-
- BUGS
- none known.
-
- NOTES
- Yes, the third parameter is d1, not d0
-
- No, the binary tree is not sorted on the actual string, but on the
- address of the associated system string.
-
- SEE ALSO
- UseObject()
- DropString()/UseString()
-
- AddTreeNode() AddWatchedTreeNode()
- FindTreeNode() AddWatchedTreeStringNode()
- FreeTreeAllNodes() RemoveWatchedTreeNode()
- RecurseTree() RemoveWatchedTreeStringNode()
- RemoveTreeNode()
- RemoveTreeStringNode()
-
- NAME
- AddWatchedSListNode -- Adds a node to a watched, prioritized singly-
- linked list.
-
- SYNOPSIS
- result = AddWatchedSListNode( list, object, pri, name )
- d0 a0 a1 d0 d1
-
- FUNCTION
- This function adds an object into a watched, singly-linked list with
- the given name at the given priority (list is ordered by priority).
-
- If any parties are interested, WatcherDispatch is called with
- W_INSERT_NODE for the flag paramter.
-
-
- INPUTS
- W_SLIST list; - a pointer to the list to which to add
- the object.
- OBJECT object; - the object to add.
- long pri; - the priority
- char *name; - the name to add it as.
-
-
- OUTPUTS
- BOOL result; - result code
-
- The result code is an integer indicating the success or failure of
- the function call. A zero value indicates that an error occured.
-
-
- RESULT
- The list has one more node on it -- the passed object.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- AddSListNode()
- FindNodePriInSList()
- RemoveSListNode() RemoveWatchedSListNode()
-
- NAME
- AddWatchedTreeNode -- adds an object into watched binary tree
-
- SYNOPSIS
- result = AddWatchedTreeNode( bt, object, key)
- d0 a0 a1 d0
-
- FUNCTION
- This function will add the object into the watched binary tree
- sorted on the key provided.
-
- The object is Used() by the UseObject() call when successfully
- placed in the binary tree.
-
- Any number of objects may exist in any number of binary trees.
- There is no restriction on how many trees an object can be
- placed (as there is on Exec lists).
-
- If any parties are interested, WatcherDispatch is called with
- W_INSERT_NODE for the flag parameter.
-
-
- INPUTS
- W_AVLTREE bt; - a pointer to the root of the watched
- binary tree.
- OBJECT object; - the object to add into the tree.
- ULONG key; - the key value to insert on.
-
- OUTPUTS
- BOOL result; - result code
-
- zero on failure. (Couldn't allocate binary node)
-
-
- RESULT
- Object is added into binary tree.
-
- BUGS
- none known.
-
- NOTES
- Uses AVL trees. Do not depend on order of insertion
- on duplicate keys. (Duplicate keys do work, though.)
-
- Remember that the keys are sorted unsigned, not signed.
-
- SEE ALSO
- UseObject()
-
- AddTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FindTreeNode()
- FreeTreeAllNodes()
- RecurseTree()
- RemoveTreeNode() RemoveWatchedTreeNode()
- RemoveTreeStringNode() RemoveWatchedTreeStringNode()
-
- NAME
- AddWatchedTreeStringNode -- add an object to a watched AVLTREE,
- keyed on a string.
-
- SYNOPSIS
- result = AddWatchedTreeStringNode( bt, object, name )
- d0 a0 a1 d0
-
- FUNCTION
- This function will add the object into the watched binary tree
- sorted on the name provided.
-
- The object is Used by the UseObject() call when successfully placed
- in the binary tree.
-
- The name uses the UseString and DropString conventions
- for system strings. The address of that string then
- determines the order the binary tree is sorted in. It
- is NOT sorted by the string itself, sorry.
-
- If any parties are interested, WatcherDispatch is called with
- W_INSERT_NODE for the flag parameter.
-
-
- INPUTS
- W_AVLTREE bt; - a pointer to the root of the watched
- binary tree.
- OBJECT object; - the object to add into the tree.
- char *name; - the name to insert on.
-
- OUTPUTS
- BOOL result; - result code
-
- zero on failure. (Couldn't allocate binary node, or system string)
-
-
- RESULT
- The object is added into the binary tree sorted on the address of
- the system string that is uniquely created on the passed name.
-
- BUGS
- none known.
-
- NOTES
- No, the binary tree is not sorted on the actual string, but on the
- address of the associated system string.
-
- SEE ALSO
- UseObject()
- DropString()/UseString()
-
- AddTreeNode() AddWatchedTreeNode()
- AddWatchedTreeStringNode()
- FindTreeNode()
- FreeTreeAllNodes()
- RecurseTree()
- RemoveTreeNode() RemoveWatchedTreeNode()
- RemoveTreeStringNode() RemoveWatchedTreeStringNode()
-
- NAME
- AddWatcherNode -- Adds a watcher to the watched variable
-
- SYNOPSIS
- result = AddWatcherNode( wv, node, pri, name )
- d0 a0 a1 d0 d1
-
- FUNCTION
- This function will add a watcher object (sometimes referred to
- as a 'director') into the WatchedVariable wv.
-
- This is a low-level routine. You should use the provided
- DIRECTOR_CLASS method. See browser.c for some examples, or the
- included ShadowLibMethods.doc for more details.
-
- If any parties are interested, WatcherDispatch is called with
- W_INSERT_WATCHER for the flag parameter.
-
-
- INPUTS
- W_VALUE wv; - the watched variable to watch
- OBJECT node; - the director to add to the watch list.
- long pri; - the priority to add the watcher as.
- char *name; - the name of the watcher.
-
- OUTPUTS
- BOOL result; - result code
-
- The result code is a boolean indicating the success or failure of
- the function call. A zero value indicates that an error occured.
-
-
- RESULT
- The director is added to the watch list.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- RemoveWatcherNode()
- AddClassWatcher()
- RemoveClassWatcher()
-
- NAME
- AllocateItem -- Allocates an item from a MemoryList
-
- SYNOPSIS
- element = AllocateItem( list )
- d0 a0
-
- FUNCTION
- Allocates an element from the list.
- The element will NOT be zeroed out, and may contain data from the
- last time that element was used.
-
- Elements are allocated 32 at a time via the allocfunc() that was
- passed to the InitTable() function. AllocateItem() doles out
- these elements one by one, automatically calling allocfunc()
- when necessary (ie: when it needs another 32 elements because it
- has no more free elements).
-
-
- INPUTS
- SEMLIST list; - the list to allocate from.
-
- OUTPUTS
- void *element; - element that is allocated.
-
- As with any allocation function, this function can return NULL for
- a failure to allocate memory.
-
-
- RESULT
- One item is allocated on the Memorylist
-
- BUGS
- none known.
-
- NOTES
- The memory returned is NOT zeroed.
-
- SEE ALSO
- InitTable()
- FreeTable()
- FreeItem()
-
- NAME
- BindSuperWatchers -- copies all watchers on the superClass' watched
- attributes to the subclass.
-
- SYNOPSIS
- result = BindSuperWatchers( class )
- d0 a0
-
- FUNCTION
- This function is called internally during METH_INIT of all classes
- and metas.
- A search is done on the immediate superClass' attributes. Any
- watchers found on the class' attribute list are copied to the
- passed class' attribute.
-
- Thus, if a new class subclassed off of WindowClass was created
- while running browser, the watcher that was watching all of the
- window classes will watch that new window class as well.
-
-
- INPUTS
- META class; - the (sub)class to bind the watchers.
-
- OUTPUTS
- BOOL result; - the result code.
-
- FALSE indicates failure to copy all the watchers. Probably ran out
- of memory allocating list nodes.
-
- RESULT
- The class' watched variables can now send out notification to the
- old class watchers for any new objects that are created and stored
- there, or for any changes in value made to the watched variable.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- BindWatchers()
- AddWatcherNode()
- AddClassWatcher()
- WatcherDispatch()
-
- NAME
- BindWatchers -- binds all object's attributes' watched wv_firstClass
- to the appropriate spot in the object's class.
-
- SYNOPSIS
- BindWatchers( object )
- a0
-
- FUNCTION
- This function is called internally during METH_INIT of all objects.
- It sets all watched variables in the object to have their
- wv_firstClass pointer pointing to the class' attributes' SList,
- like it is supposed to.
-
- This allows notification of any changes to the watched variable to
- be sent out on a class basis -- any object of the class will
- attempt to send notification to both the specific object, and
- the associated class.
-
- An example is in browser.c which is notified whenever any object
- is added to the ATTR_GUICHILDREN of any object whose class is
- a descendent of WindowClass.
-
-
- INPUTS
- OBJECT object; - the object to bind the watchers.
-
- OUTPUTS
-
-
- RESULT
- The object's watched variables can now send out notification to the
- class watchers.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- BindSuperWatchers()
- AddWatcherNode()
- AddClassWatcher()
- WatcherDispatch()
-
- NAME
- BlockMethod -- [un]blocks via a METH_FLAG_PREBLOCK, the method
- in a given class.
-
- SYNOPSIS
- BlockMethod( class, name, pri, block )
- a0 a1 d0 d1
-
- FUNCTION
- This function will search the class for a method of the given name.
- If pri is non-zero, the patched verbs list of the class is searched
- for a method patch of the given name and priority.
-
- This handle is then either PRE_BLOCK'd or un-PRE_BLOCK'd,
- according to the block flag.
-
-
- INPUTS
- META class; - the class where the method is found.
- char *name; - the name of the method to [un]block.
- WORD pri; - the priority (or nearest priority) of where
- the block should take effect.
- If pri is non-zero, a patch of that pri must
- exist.
- WORD block; - whether to block (TRUE) or to unblock (FALSE)
-
- OUTPUTS
- none
-
-
- RESULT
- A method may be [un]blocked.
-
- BUGS
- none known. Not yet tested! (07 Oct 1992)
-
- NOTES
-
- SEE ALSO
- DSM() DoShadow()
- InvalidateCache()
- SetMethodArgs()
- AddMethods()
- DestroyMethodTable()
- FindMethodHandle()
- RemoveAllPatches()
- SetupMethodTags()
-
- NAME
- ChangeWatchedValue -- Changes a watched variable's value.
-
- SYNOPSIS
- ChangeWatchedValue( wv, new )
- a0 d0
-
- FUNCTION
-
- Changes the watched variable to the passed new value.
-
- If any parties are interested, WatcherDispatch is called with
- either W_CHANGE_ZERO or W_CHANGE_NON_ZEROin the flag parameter.
-
-
- INPUTS
- W_VALUE wv; - a watched variable to change.
- long new; - the value to change to.
-
- OUTPUTS
-
-
- RESULT
- The value is changed, and all parties notified.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- WatcherDispatch()
-
- NAME
- CopyDefaultAttributes -- Copy the default attrs into the instance
-
- SYNOPSIS
- CopyDefaultAttributes( object )
- a0
-
- FUNCTION
- This function will copy the default values, specified in the
- object's class, into the object. It is executed by both MetaClass
- and MetaCluster, and by both rootClass and rootCluster in the
- METH_CREATE method.
-
- It assumes the object is already filled with ZEROs.
-
-
- INPUTS
- OBJECT object; - The object whose attributes should be initialized.
-
- OUTPUTS
- none
-
-
- RESULT
- The object's attributes are initialized to the attribute default
- values stored in the object's class.
- Object is assumed to have already been initialized to ZEROs.
-
- BUGS
- none known.
-
- NOTES
- object is a required parameter.
-
- SEE ALSO
- PrepareAttrTags()
- AddAttributes()
- FreeAttributes()
- FindAttribute()
- FindAttrDefn()
-
- NAME
- CreateMeta -- Creates a self-referencing class description.
-
- SYNOPSIS
- meta = CreateMeta( description )
- d0 a0
-
- FUNCTION
- This function creates a Meta.
-
- A Meta is a class whose class is itself. Metas are useful for
- describing Classes and such. The current system creates two
- Metas: MetaClass and MetaCluster.
-
- The description is used to create the Meta using the attributes
- and superClass pointers. The superClass field, the attribute
- table and the method table are all filled in. The name is NOT,
- nor is any other information in the description touched.
-
- The passed description's object and class pointers are set up as
- the allocated meta, the method is initialized either to METH_INIT
- (if the passed description's method as NULL) or left as passed
- (if not NULL).
-
- CreateMeta then returns "DSM(INVOKE_FIND_SELECTOR, description)".
-
- This implies several things:
-
- You can create meta structures that need initialization by
- passing the appropriate arguments in the InitMeta structure.
- See the InitMeta structure for more details.
-
- Your METH_INIT methods should, then, -do-the-right-thing- when
- passed its own meta, rather than a proper instance of
- that meta. The correct method for checking for such an event
- is to compare 'object' with 'object->cob_class' as in:
-
- MyMethod(METHOD_ARGS, MYMETHODARGS)
- {
- if (object == object->cob_class)
- {
- /*
- * we were passed a meta, so
- * do what we needed to do with that.
- */
- } else
- {
- /*
- * We were passed a proper instance, so do
- * what is necessary here.
- */
- }
- }
- Specifically, you should NOT do a comparison between 'object'
- and 'class'. Class can change if called as a superclass method.
- The object might still be a meta, just not THAT method's meta....
-
- As always, the following methods should also handle being sent a
- Meta: METH_DESTROY, METH_REMOVE.
-
- METH_SUB should also handle Metas by filling in the superClass
- pointer and passing the arguments to CreateMeta.
- The following code segment may be useful:
-
- MethodMetaSub(METHOD_ARGS, name, superClass, attrList, verbList)
- {
- if (!superClass)
- superClass = object;
-
- if (object == object->cob_class)
- {
- struct InitMeta *im;
-
- im = (struct InitMeta *)&object;
-
- im->im_object = im->im_class = NULL;
- im->im_method = NULL;
- im->im_super = superClass;
- return CreateMeta(im);
- }
-
- .
- .
- .
- }
-
- A consequence of using METH_SUB to create new Metas is that
- the initialization parameters are truncated to match the
- METH_SUB parameter description, which might not pass all the
- required parameters into the InitMeta structure sent to
- CreateMeta! Please remember what you are doing.
-
- The description structure that is passed is a fixed length header
- with a variable length number of additional arguments (which should
- match the initialization routine CreateMeta calls: either the contents
- of description->im_method OR METH_INIT if that is NULL). As a result,
- this argument list MUST be terminated by a METHOD_END. Note that
- all method invocations have a METHOD_END located one argument
- passed their last defined argument, thus allowing the above code to
- work properly.
-
- Your initialization routine is responsible for setting the Meta's name
- and adding the meta to ShadowBase->sb_metaTree. However, it should
- specifically NOT setup the attribute tables and method tables (like
- it would in the case of a new class) as CreateMeta has already
- done that for you.
-
- The instances of Metas have, likewise, the same attributes as the Meta
- (as part of their instance, where the Metas have those attributes in
- both the INSTANCE and in their attribute description table).
-
- Reminder:
- the METH_REMOVE of the meta must distinguish between the case
- where the passed object != meta (meaning the object is an
- instance of Meta, and so should be removed from the
- ATTR_INSTANCETREE of the object->cob_class) and the case where
- object == meta (meaning the object *is* the meta, and should be
- removed from the system's metaTree -- &ShadowBase->sb_metaTree).
-
- Similarly for METH_DESTROY -- don't drop the object's cob_class
- when you destroy the meta ie: object == object->cob_class), and
- do transfer the class:
- if (object == class) IpcARGTransfer(msg, 1);
-
-
- INPUTS
- struct InitMeta *im; - the initialization description. See includes
-
- OUTPUTS
- META meta; - the meta that was created. NULL if error.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- UseObject()
- DropObject()
- FindInstanceOfMeta()
-
- NAME
- CreateObject -- creates an object with the same data as the ptr.
-
- SYNOPSIS
- object = CreateObject( ptr, size )
- d0 a0 d0
-
- FUNCTION
- This function creates a ClasslessObject, which can be UseObject()'d
- and DropObject()'d at will, whose included data is the data
- located in ptr, covering "size" bytes.
-
- If given both a non-NULL pointer and non-zero size, it allocates
- an object of sizeof(struct ClasslessObject)+size and sets up
- the fields according to what a ClasslessObject should look like:
-
- clb_size = size;
- clb_useCount = 1;
- clb_class = NULL;
-
- As noted, the returned object is Use'd once, so it should be
- DropObject()'d when its life expires.
-
-
- INPUTS
- void *ptr; - the object to effect the change upon.
- ULONG size; - the size of the data pointed to by ptr.
-
- OUTPUTS
- OBJECT object; - the allocated object with the (optional) passed
- data. NULL if error.
-
-
- RESULT
- A new ClasslessObject is created.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- UseObject()
- DropObject()
-
- NAME
- DestroyMethodTable -- frees the array of methods.
-
- SYNOPSIS
- DestroyMethodTable( table )
- a0
-
- FUNCTION
- This function will destroy the MethodTable's array of
- MethodHandlers (usually the class' meta_verbs field).
-
- It resource-tracks the procObject, defnObject, and method names
- in the MethodHandler elements. At this point, the routine will
- DropObject() or DropIPCPort() or DropString() these fields.
-
-
- INPUTS
- struct MethodTable *table; - required parameter. Usually found in
- class->meta_verbs.
-
- OUTPUTS
-
-
- RESULT
- The array, if a non-NULL ptr, is freed.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DSM() DoShadow()
- InvalidateCache()
- SetMethodArgs()
- AddMethods()
- FindMethodHandle()
- BlockMethod()
- RemoveAllPatches()
- SetupMethodTags()
-
- NAME
- DropObject -- resource tracking for shadow objects.
-
- SYNOPSIS
- DropObject( object )
- a0
-
- FUNCTION
- This function decrements the object's cob_useCount.
-
- You should Drop() an object when you free a structure that had a
- pointer-to-object in it. In addition, certain method calls, like
- METH_INIT return an object to you. When you are done using the
- pointer, you are expected to drop the pointer.
-
- A word about self-referencing. Self-referncing is an evil problem
- in useCount systems. You should DropObject() all self-references
- during the METH_REMOVE call of an object. For instance, if your
- class maintained a binary tree of gadget objects, and these
- gadget objects pointed back to the window object, the
- IDCMP_WINDOWCLOSE should do a METH_REMOVE on the window, which in
- turn should METH_REMOVE it's gadgets, and those gadgets should
- remove all references to the window object during that METH_REMOVE
- call.
-
- If the useCount of the object drops to zero furing DropObject(),
- the object's destructor (METH_DESTROY) is called. If the object
- in question has no class, than it is assumed to be a
- ClasslessObject, and the clb_size is looked at. If this field
- is non-zero, the object is freed, with
- "FreeMem(object, object->clb_size);"
-
- You must be careful when designing asynchronous METH_DESTROY
- methods -- please see IpcItemTransfer() for further details.
-
-
- INPUTS
- OBJECT object; - the object to effect the change upon.
-
- OUTPUTS
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- UseObject()
- IpcItemTransfer()
- Introduction.doc :: resource tracking
-
- NAME
- DropString -- Removes a reference to a system string.
-
- SYNOPSIS
- DropString( buffer )
- a2
-
- FUNCTION
- This function searches the system string list for the system
- string corresponding to the passed buffer, then decrements
- the internal usage counter for that system string by one.
-
- If the counter becomes zero, that system string is freed from
- memory.
-
- If no string can be found to match buffer, no action is taken.
-
-
- INPUTS
- char *buffer; - equivalent string to the system string that you
- want the system to drop a reference to.
-
- OUTPUTS
-
-
- RESULT
- The system string corresponding to the passed buffer has one
- fewer references to it.
-
- BUGS
- none known.
-
- NOTES
- The buffer should be word-aligned for faster access. long-word
- aligned is preferred.
-
- SEE ALSO
- UseString()
- QuickUseString()
- FindString()
- QuickDropString()
-
- NAME
- DSM -- parses out the requested method, calls and/or sends out
- the appropriate function(s)/message(s)
-
- SYNOPSIS
- result = DSM(flags, arguments )
- d0 d1 a1
-
- FUNCTION
- This function is the work horse of the entire system. It is
- responsible for sending off all METHODs, whether synchronously,
- asynchronously, or as a function call. In addition, it also sends
- off all method patches as requested.
-
- DSM() takes a number of flags which are found in <shadow/message.h>.
- They are meant to override similar flags which are located in the
- METHOD_TAG definition of each individual method. Following is their
- meaning:
- INVOKE_CALL - DEFAULT assumption -- calls method as function
- unless specified otherwise in the METHOD_TAG
-
- INVOKE_SYNC - Overrides the method's mtag_threadstat field.
- The method is sent as a synchronous message
- to the method's destination process [usually
- mtag_procObject; see: SetupMethodTags and
- INVOKE_WITH_PROCESS], unless the calling
- process belongs to a superset (non-proper)
- of the destination's process, in which case
- the method is called as a function.
-
- INVOKE_ASYNC - Overrides the method's mtag_threadstat field.
- The method is sent as an asynchronous message
- to the method's destination process [usually
- mtag_procObject; see: SetupMethodTags and
- INVOKE_WITH_PROCESS], unless the calling
- process belongs to a superset (non-proper)
- of the destination's process, in which case
- the method is called as a function.
-
- INVOKE_FORCE - Used in onjunction with above flags. See
- next three flags.
-
- INVOKE_FORCE_SYNC - Overrides the method's mtag_threadstat field.
- The method is sent as a synchronous message
- unless the calling process is exactly
- equivalent to the destination process, in
- which case the method is called as a funcion.
-
- INVOKE_FORCE_ASYNC- Overrides the method's mtag_threadstat field.
- The method is ALWAYS sent as an asynchronous
- message. Irregardless of calling/destination
- process.
-
- INVOKE_FORCE_CALL - This is used to override the method's
- mtag_threadstat and force a function call
- equivalent.
-
- INVOKE_WITH_PROCESS-This indicates that the passed argument array
- has a preceding process object which should
- be used as the destination process for the
- method. The process will only be used
- providing that it is required by the method
- (ie: that the method is called synchronously
- or asynchronously and meets the requirements
- of the calling/destination process as
- described in the INVOKE_[FORCE_][A]SYNC
- flags above), AND if the
- INVOKE_IGNORE_PROCESS flag is not set in the
- mtag_threadstat field of the method. The
- INVOKE_IGNORE_PROCESS is the exact equivalent
- of the INVOKE_WITH_PROCESS. However, because
- of the difference in both meaning and
- placement, the INVOKE_WITH_PROCESS flag name
- should be used with DSM(), and the
- INVOKE_IGNORE_PROCESS should be used with
- the mtag_threadstat.
-
- INVOKE_FROM_SUPER - This flag indicates the wish to call a passed
- class' superclass. The second field of the
- arguments will be -modified- by DSM() to the
- class' superclass, and the method then
- invoked normally. Additional doMethod
- function callback checking will occur -- both
- for the original class and the superclass.
-
- INVOKE_FIND_SELECTOR
- - The selector is looked up in the system's
- hashtable of strings using the FindString()
- SHADOW library call. The address of this
- system string is used to select the method
- to call.
-
- INVOKE_RETURN_MSG - The DSM() call returns a message which can be
- used to later generate the actual method as
- specified in the passed arguments. All
- resource tracking on the arguments is done
- within DSM(). The returned message can
- be junk()'d with the JunkIPCMessage()
- SHADOW library call, or the method can be
- sent as an argument to another function,
- and in that method you can call the
- ParseShadowMessage() to call the method
- associated with the message. Please see
- the examples in ShadowLibFuncs.doc
- under the PreParseShadow() .lib function.
-
-
- If the "flags" argument specifies that the methods should be forced
- to send all methods INVOKE_ASYNC or INVOKE_FORCE_ASYNC, then a single
- message is sent to the primary handle's procObject asynchronously
- with the function callback set back to DSM. When DSM() is then
- called by the other proces (the message having been parsed out by
- MessageParse(), usually handled by ParseShadowMessage()), the method
- and all of its patches are sent out without the INVOKE_ASYNC
- specification. This corrects the case where a patch is supposed
- to be able to -synchronously- control any subsequent patches
- (METH_FLAG_CHECK_CONTINUE). Obviously if all methods and all
- patches were sent out asynchronously, there would be no chance
- for a synchronous-type behaviour to act correctly. Therefore,
- the initial send is asynchronous to the caller, but the complete
- method handling, including synchronous calling of patches,
- occurs synchronously to the called process.
-
- Consequently, if the method itself (as represented in its METHOD_TAG
- description) is flagged with INVOKE_FORCE_ASYNC, and DSM() is called
- with the INVOKE_ASYNC flag, then there are actually -two- messages
- that are sent. One is the message described above which handles the
- synchronous patch-handling asynchronously to the calling process,
- the other message occurs when the method is processed in the called
- task -- the method was created as being invoked asynchronously,
- independently from where it is called, so another message is sent
- back to the same process!
-
- Representing the method as INVOKE_ASYNC, as opposed to
- INVOKE_FORCE_ASYNC, will avoid this problem, although in this case
- you may not be able to make the process asynchronous enough to
- avoid the cases where synchronous behaviour is unwanted.
-
- The best way to avoid these problems is to use the
- INVOKE_FORCE_ASYNC flag in METHOD_TAGs as little as possible, and
- only call DSM() with the asynchronous flag as needed. The .lib
- functions DoShadowAsync(), DoShadowInProcessAsync(), etc. all
- call DSM() with the INVOKE_ASYNC bit set.
-
- If you cannot avoid these issues, you may want to consider creating
- your own process class for the method, allowing, therefore, an
- INVOKE_ASYNC bit to correctly be asynchronous to every process
- -except- when called from within this "double-nested" DSM().
- In that case, because the calling process and the method-destination
- process are equivalent, the method is invoked via the function,
- and not another message. There is more overhead in creating your
- own process class (an extra CreateSubClass() call), but it may be
- worth your trouble....
-
-
-
- In addition to these passed flags, many of the mtag_flags located in
- the method description are used to enhance DSM()'s capabilities of
- sending methods across process boundaries. These flags can be found
- in <shadow/misc.h>:
-
- METH_FLAG_OBJECT - The mtag_procObject is interpreted as the
- destination process.
- METH_FLAG_PORT - The mtag_procObject is interpreted as an
- IPCPort to which method-messages are sent.
- METH_FLAG_CLASS - The mtag_procObject is interprted as a
- class of process objects. This class is
- instantiated, and the resulting process
- object is used as the destination for
- that particular invocation.
-
- METH_FLAG_OBJECT_AS_DEST
- - The object inside of the passed arguments
- (ie: *(OBJECT *)arguments) is considered the
- destination for the method. This is
- particularly useful for process methods which
- must (for reasons of port allocation or other
- Signal-bit allocation, etc.) be run in the
- process with which the process-object
- corresponds.
-
- METH_FLAG_SPEC - The mtag_procObject is interpreted as a
- pointer to a struct MethInvokeSpec
- [see: <shadow/method.h>], the complete
- meaning of which depends on the above four
- flags in the following manner:
-
- METH_FLAG_SPEC | METH_FLAG_OBJECT
- mis_instanceName is the name of the process object to use
- as the destination object.
- mis_className is the class name of the class of the
- above process object.
- mis_metaName is the meta's name of the meta of the
- above class. Usually this is
- META_CLASS.
-
- METH_FLAG_SPEC | METH_FLAG_PORT
- mis_instanceName is the name of the IPCPort to use as the
- destination port. This port will NOT
- be created, but must exist when the
- method is called.
- mis_className is NULL
- mis_metaName is NULL
-
- METH_FLAG_SPEC | METH_FLAG_CLASS
- mis_instanceName is NULL
- mis_className is the class name of the process to
- create.
- mis_metName is the meta's name of the meta of the
- above class. Usually this is META_CLASS.
-
- METH_FLAG_SPEC | METH_FLAG_OBJECT_AS_DEST
- the METH_FLAG_SPEC is meaningless in this case as the
- METH_FLAG_OBJECT_AS_DEST never uses the mtag_procObject
- field.
-
-
- When the process/port is looked-up/created,
- the process/port may replace the
- MethInvokeSpec structure, eliminating the
- need to lookup the object/class/port again.
- To do this, set the SPEC_SAVE_BINDING flag
- in the mis_flags field of the MethInvokeSpec
- structure.
-
-
- The following METH_FLAGs are passed in at method or patch creation
- in the MethodTag mtag_flags field:
-
- METH_FLAG_[POST|PRE]_BLOCK
- - ends the sending of methods off as DSM()
- works from the highest priority patch, to
- the normal MethodHandle, to the lowest
- priority patch. POST_BLOCK ends the
- method chain after -that- method in the
- patch-chain is sent off, PRE_BLOCK ends it
- BEFORE that method is sent off.
-
- METH_FLAG_NO_RTRN
- - informs DSM() that a patch or method has no
- return value. By default, all methods and
- patches have return values.
- Note that this is a change from SHADOW 4!
-
- METH_FLAG_CHECK_CONTINUE
- - checks the return value returned in d1
- (that's d1, not d0). If d1 is TRUE, then
- the method-chain is continued, if FALSE
- (zero), then the method chain ends at that
- point.
-
-
- A method-chain exists whenever a method is patched. These patches
- are called from high priority to zero, when the regular handle is
- called, and then lower priority patches are called. This chain
- of method calls can be terminated by the *_BLOCK or CHECK_CONTINUE
- flags mentioned above. Patches are discussed in more detail in both
- the ShadowLibraryMethods.doc and the Introduction.doc.
-
-
- Thus, we have a picture of DSM(). First, the doMethod() callback of
- the passed class is checked to see if someone else wants to process
- the method calls (see NOTE: below). Then , if necessary,
- the superclass is loaded and the same doMethod() check is made.
-
- The selector is rendered into a legal system selector, and the
- method found in the class or class hierarchy. The method is then
- checked to see if it's merely a function call, or a series of
- function/[a]synchronous calls in a patch-chain. If the former,
- the method is invoked, if the latter, a series of actions are taken
- to invoke the method correctly, whether as a function call (as an
- INVOKE_[A]SYNC might turn out to be), or as a message of some kind,
- or as a series of function calls and message sends.
-
- To avoid headaches, just use the Do*Shadow*() calls in the .lib
- instead....
-
- INPUTS
- void **arguments; - a pointer to the arguments. First should be the
- object, then a valid class, then a method, then
- the rest of the arguments according to the
- ArgumentTag structure, ending with a METHOD_END
- (0x80000001)
- ULONG flags; - if low byte non-zero, treat as a specification
- for the type of method to send (INVOKE_CALL,
- etc.). A INVOKE_FORCE alone specifies
- that the method should be called. The flag
- affects any method patches as well.
- INVOKE_SUPER indicates the method should be
- sent to the superclass of the class as poassed
- in arguments[1].
- INVOKE_FIND_METHOD indicates that the method
- needs to be lookup up in the systemString via
- the FindString call.
-
- OUTPUTS
- void *result; - result from method parse.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- DSM() caches methods for faster lookups (a bit less than thrice as
- fast in worst case function calls).
-
- DSM() checks the class' doMethod function callback both BEFORE and
- AFTER any INVOKE_SUPER handling. This callback should act like
- DSM(), if you want to change the way DSM() works. The callback
- does, however, take its parameters in d0/a0 not d1/a1. The callback
- is located in the class structure -- inside of the struct CoreClass,
- to be exact [<shadow/coreMeta.h>]. As DSM() searches up the class
- hierarchy for the method, each class' doMethod() callback is
- checked. if it exists, the function is then called.
-
- Use the Do*Shadow*() method calls instead!
- SEE ALSO
- Do*Shadow*()
- InvalidateCache()
- SetMethodArgs()
- AddMethods()
- DestroyMethodTable()
- FindMethodHandle()
- BlockMethod()
- RemoveAllPatches()
- SetupMethodTags()
-
- NAME
- FindAttrDefn -- Finds the attribute structure in the class
-
- SYNOPSIS
- attribute = FindAttrDefn( class, name )
- d0 a0 a1
-
- FUNCTION
- This function finds the Attribute structure (the element in the
- class' array) of the specified class.
-
- If the class has a callback attribute function, that function is
- called instead.
-
- Otherwise, the array is radix searched for the attribute whose
- name corresponds to FindString(name).
-
-
- INPUTS
- META class; - the class whose attribute is wanted
- returns NULL for a NULL class.
- char *name; - the name of the attribute to find.
-
- OUTPUTS
- struct Attribute *attribute; - pointer to the Attribute structure as
- specified in the class.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- The attribute callback function is called:
- ccl_attrDefnFunc() and is located in the struct CoreClass
- described in <shadow/coreMeta.h>.
-
- SEE ALSO
- PrepareAttrTags() FindString()
- AddAttributes()
- CopyDefaultAttributes()
- FreeAttributes()
- FindAttribute()
-
- NAME
- FindAttribute -- Finds the instance of the attribute in the object
-
- SYNOPSIS
- attribute = FindAttribute( object, name )
- d0 a0 a1
-
- FUNCTION
- This function will find the specified structure inside of the object
- and return the address of that structure.
-
- Calls FindAttrDefn() on the object's class.
-
-
- INPUTS
- OBJECT object; - the object whose attribute is wanted.
- returns NULL for a NULL object, or
- an object with a NULL class.
- char *name; - the name of the attribute to find.
-
- OUTPUTS
- void *attribute; - pointer to the object's attribute. This
- pointer points to the insides of an object.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- Calls FindAttrDefn internally.
-
- SEE ALSO
- PrepareAttrTags()
- AddAttributes()
- CopyDefaultAttributes()
- FreeAttributes()
- FindAttrDefn()
-
- NAME
- FindInstanceOfMeta -- Bi-level search for instances of a Meta (Classes!)
-
- SYNOPSIS
- class = FindInstanceOfMeta( className, metaName )
- d0 a0 a1
-
- FUNCTION
- This function is useful for finding a Class. A Class always resides
- in the ATTR_INSTANCETREE of its defining Meta (until removed via the
- METH_REMOVE method). The Metas all reside in ShadowBase->sb_metaTree.
- Therefore, it takes two FindWatchedTreeStringNode() calls to find a
- class (or Cluster).
-
- This is how FindShadowClass() and FindShadowCluster() are #defined....
-
-
- INPUTS
- char *className; - the name of the class you are looking for.
- char *metaName; - the name of the Meta that the class is in.
-
- OUTPUTS
- OBJECT class; - the pointer to the class. NULL if can't find.
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- You should DropObject() the class when you are finished using it.
-
-
- SEE ALSO
- UseObject()
- DropObject()
- CreateMeta()
- FindNamedObject()
-
- NAME
- FindMethodHandle -- finds the associated handle in the class.
-
- SYNOPSIS
- handle = FindMethodHandle( class, method )
- d0 a0 a1
-
- FUNCTION
- This function will search the class' verb table for the
- required method. It does not look in any superclasses to
- find it.
-
-
- INPUTS
- META class; - the (optional) class in which to find the method.
- char *method; - the name of the method to look for. MUST be the
- system string equivalent (you can get this from
- the FindString() function.
-
- OUTPUTS
- struct MethodHandle *handle; - the returned handle. NULL if not
- found.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DSM() DoShadow()
- InvalidateCache()
- SetMethodArgs()
- AddMethods()
- DestroyMethodTable()
- BlockMethod()
- RemoveAllPatches()
- SetupMethodTags()
-
- NAME
- FindNamedObject -- Tri-level search for instances of a Class of a Meta
-
- SYNOPSIS
- object = FindNamedObject( instanceName, className, metaName )
- d0 d0 a0 a1
-
- FUNCTION
- This function is useful for finding a named OBJECT like a process.
- A Process' Class always resides in the ATTR_INSTANCETREE of its
- defining Meta (until removed via the METH_REMOVE method). Likewise,
- the process OBJECT always resides in the ATTR_INSTANCETREE of its
- defining process class. Therefore, it takes three
- FindWatchedTreeStrngNode() calls to find a named object.
-
-
- INPUTS
- char *instanceName; - the name of the object we're looking for.
- char *className ; - the name of the class you are looking for.
- char *metaName ; - the name of the Meta that the class is in.
-
- OUTPUTS
- OBJECT object ; - the pointer to the object. NULL if can't find.
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- You should DropObject() this object when you are finished using it.
-
-
- SEE ALSO
- UseObject()
- DropObject()
- CreateMeta()
- FindInstanceOfMeta()
-
- NAME
- FindNodePriInSList -- Finds an object in the singly linked list
-
- SYNOPSIS
- object = FindNodePriInSList( list, pri, name )
- d0 a0 d0 a1
-
- FUNCTION
- This function finds an object in a singly linked list with the
- given name at the given priority (list is ordered by
- priority).
-
-
- INPUTS
- SList *list; - a pointer to the list in which to find
- the object.
- long pri; - the priority
- char *name; - the name it was added as.
-
-
- OUTPUTS
- OBJECT object; - the object, if found. NULL otherwise.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- The found object is UseObject()'d, please DropObject() it when you
- are finished using the pointer.
-
- SEE ALSO
- AddSListNode() AddWatchedSListNode()
- RemoveSListNode() RemoveWatchedSListNode()
-
- UseObject()
- DropObject()
-
- NAME
- FindString -- Find a system string
-
- SYNOPSIS
- string = FindString( buffer )
- d0 a2
-
- FUNCTION
- This function hashes the buffer string and searches on the
- collision binary tree for any matches.
-
- It will return the system string, if it finds it. It will NOT
- increment the internal useCount, so you should not use what is
- returned as either a system string, nor even as a string, but
- merely as an address you are searching a table for -- and
- even then, you must be careful of race conditions, the address
- should remain valid for the entire time you are searching a
- table or structure, or the table/structure must be locked in
- memory during the time you look up the string and the time
- you are searching the table.
-
-
- INPUTS
- char *buffer; - the buffer whose system string you want to find.
- Given a NULL, will
- return a NULL
-
- OUTPUTS
- char *string; - the string, if found. NULL if no string.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- The buffer should be word-aligned for fast access and long-word
- aligned for fastest access.
-
- SEE ALSO
- UseString()
- QuickUseString()
- DropString()
- QuickDropString();
-
- NAME
- FindTreeNode -- Finds the object in the binary tree
-
- SYNOPSIS
- object = FindTreeNode( bt, key )
- d0 a0 d0
-
- FUNCTION
- This function returns the first object in the binary tree that matched
- the key passed to the function.
-
- Note that a corollary function FindTreeStringNode() is usually defined
- as FindTreeNode(bt, FindString(name)).
-
- The object is Used() via the UseObject() call. When the pointer that
- is returned is no longer needed, it should be Drop()'d via the
- DropObject() call.
-
-
- INPUTS
- AVLTREE *bt; - a pointer to the root of the binary tree.
- ULONG key; - the key to look for.
-
- OUTPUTS
- OBJECT object; - the object that is found
-
- NULL is returned if no object is found.
-
- RESULT
- The node is located in the binary tree.
-
- BUGS
- none known.
-
- NOTES
- Please DropObject() any objects returned when no longer needed.
- Remember that the keys are sorted unsigned, not signed.
-
- SEE ALSO
- UseObject()/DropObject()
-
- AddTreeNode() AddWatchedTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FreeTreeAllNodes() RemoveWatchedTreeNode()
- RecurseTree() RemoveWatchedTreeStringNode()
- RemoveTreeNode()
- RemoveTreeStringNode()
-
- NAME
- FreeTreeAllNodes -- Frees all nodes in a particular binary tree
-
- SYNOPSIS
- FreeTreeAllNodes( bt )
- a0
-
- FUNCTION
- This function will remove all nodes off of the binary tree, dropping
- all objects, and all strings.
-
- The binary tree is assumed to contain objects sorted on a string as
- a key. Please do not call it on any other type of binary tree, as
- it would be dropping potentially non-existant string objects.
-
- V4.2 UPDATE! You may now call it with a binary tree that is sorted
- on keys identical to the pointer to the objects each node holds.
- ie: keys added with:
- AddTreeNode(&bt, object, object);
- -or- with keys of less than 256, which are assumed to be merely
- longwords and not pointers to strings....
-
-
- INPUTS
- AVLTREE *bt; - a pointer to the root of the binary tree.
-
- OUTPUTS
-
-
- RESULT
- bt is now a pointer to an empty binary tree.
-
- BUGS
- none known.
-
- NOTES
- Don't call this function on a binary tree sorted by keys that aren't
- system strings, aren't less than 256 and aren't equal to the
- corresponding object.
-
- SEE ALSO
- AddTreeNode() AddWatchedTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FindTreeNode() RemoveWatchedTreeNode()
- RecurseTree() RemoveWatchedTreeStringNode()
- RemoveTreeNode()
- RemoveTreeStringNode()
-
- NAME
- FreeAttributes -- Frees all Attribute structures for the class
-
- SYNOPSIS
- FreeAttributes( table )
- a0
-
- FUNCTION
- This function will free the array of Attributes in the
- AttributeTable. Called during METH_DESTROY for classes and metas.
-
-
- INPUTS
- struct AttributeTable *table; - pointer to the attribute table to
- free. Probably a pointer into a
- class that is going away.
-
- OUTPUTS
- none
-
-
- RESULT
- The memory allocated in that table is freed. The Table structure
- itself is NOT freed.
-
- BUGS
- Should probably be called DestroyAttributeTable()
-
- NOTES
- table is a required parameter
- This is a system function, and probably not something that you will
- need to call.
-
- SEE ALSO
- PrepareAttrTags()
- AddAttributes()
- CopyDefaultAttributes()
- FindAttribute()
- FindAttrDefn()
-
- NAME
- FreeClassWatchers -- frees all the watchers in the class' attributes
-
- SYNOPSIS
- FreeClassWatchers( class )
- a0
-
- FUNCTION
- This function frees all watchers left on any of the class'
- attribute-watching SLists.
-
-
- INPUTS
- META class; - the class whose attributes' watchers need to be
- removed.
-
- OUTPUTS
-
-
- RESULT
- All watchers in a class are removed.
-
- BUGS
- none known.
-
- NOTES
- For some reason, class watchers need to be removed from the class
- when the class is removed.
-
- Therefore, the METH_REMOVE for metas and roots calls this function.
-
- SEE ALSO
- FreeObjectWatchers()
- AddClassWatcher()
-
- NAME
- FreeItem -- Frees an element belonging to a MemoryList
-
- SYNOPSIS
- FreeItem( list, ptr )
- a0 a1
-
- FUNCTION
- This function frees an element that was allocated via the
- AllocateItem() function. The element may, or may not, be returned
- to Exec's free memory pool, but may, thereafter, be re-used by
- AllocateItem() for some other program.
-
-
- INPUTS
- SEMLIST list; - the MemoryList the element belongs to.
- void *ptr; - the element pointer
-
- OUTPUTS
-
-
- RESULT
- The element is returned to be re-used by AllocateItem for the
- specified MemoryList.
-
-
- BUGS
- Infinite loop occurs if ptr was not on the MemoryList to begin with.
-
- NOTES
- The MemoryList passed MUST be the MemoryList from which the element
- was allocated.
-
- SEE ALSO
- InitTable()
- AllocateItem()
- FreeTable()
-
- NAME
- FreeObjectWatchers -- frees all the watchers in the object's vars.
-
- SYNOPSIS
- FreeObjectWatchers( object )
- a0
-
- FUNCTION
- This function removes all watchers from all variables in the object.
-
-
- INPUTS
- OBJECT object; - the object whose watched variables need to be
- removed.
-
- OUTPUTS
-
-
- RESULT
- All watchers of all watched variables in the object are removed.
-
- BUGS
- none known.
-
- NOTES
- This function, as opposed to FreeClassWatchers(), can be called in
- the METH_DESTROY. The Metas and Roots currently call this function.
-
- SEE ALSO
- FreeClassWatchers()
- AddClassWatcher()
-
- NAME
- FreeTable -- free all the memory nodes on the MemoryList
-
- SYNOPSIS
- FreeTable( list )
- a0
-
- FUNCTION
- This function frees all resources that the MemoryList acquired
- during run-time. This means that any outstanding MemoryNodes are
- thereafter freed -- and therefore not usable to whomever may own
- them. No attempt is made to ensure all items have been released
- before all outstanding MemoryNodes are freed by the freefunc()
- originally passed to InitTable.
-
- FreeItem automatically frees MemoryNodes when it "feels" there are
- plenty of free elements available for use. However, that means
- that even when all elements are FreeItem()'d, there will still be
- many MemoryNodes on the MemoryList. This function will free those
- remaining MemoryNodes.
-
-
- INPUTS
- SEMLIST *list; - the MemoryList to purge.
-
- OUTPUTS
-
-
- RESULT
- The MemoryList no longer contains any outstanding resources.
-
- BUGS
- none known.
-
- NOTES
- The notion of '"feels" there are plenty of free elements' is
- intentionally vague.
-
- SEE ALSO
- InitTable()
- AllocateItem()
- FreeItem()
-
- NAME
- GetObject -- Semaphored access to an object in a public area.
-
- SYNOPSIS
- object = GetObject(objectPtr )
- d0 a1
-
- FUNCTION
- In some attributes, there may be object pointers that you need
- to retrieve from that attribute. On the other hand, somebody else
- might change it at the same time.
-
- This function uses the ShadowBase->sb_semSemaphore to protect the
- access to the objectPtr. The object that is returned is returned
- Use()'d, so when you are done with the object you should call
- DropObject(object) on it.
-
-
- INPUTS
- OBJECT *objectPtr; - the pointer to the structure element that
- holds the object pointer you want.
- OUTPUTS
- void *object; - the object that *objectPtr points to.
-
- RESULT
- object returned is UseObject()d once.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- RemoveObject()
- SetObject()
-
- NAME
- GetShadowError -- Get an error code from SHADOW
-
- SYNOPSIS
- result = GetShadowError()
- d0/d1
-
- FUNCTION
- This function retrieves the last SHADOW error and suberror that
- occurred within the calling process' context.
-
- This is useful to use when you need to differentiate between
- a failure to send a message, and an asynchronous send which ALWAYS
- returns a NULL, or a successful, but NULL-returning, method.
-
- You should ClearShadowError() first, of course....
-
- /*
- * The following is included for clarity, but is actually
- * present in the shadow_proto.h include file.
- */
- #define ClearShadowError() SetShadowError(0,0);
-
- .
- .
- .
-
- union {
- double tempD;
- ULONG tempV[2];
- } retval;
-
- ClearShadowError()
- if (!DoShadow(object, NULL, DO_SOMETHING, METHOD_END))
- {
- retval = GetShadowError();
- /*
- * tempV[0] is the error code.
- * tempV[1] is reserved at the moment, and is garbage for now.
- */
- switch(errorCode = retval.tempV[0])
- {
- /*
- * The following flags are from misc.h
- */
- case 0:
- /*
- * No Error!
- */
- case NO_SHADOW_PROCESS:
- /*
- * Could not retrieve an error because the current
- * process is not registered with SHADOW.
- */
- case CANNOT_ALLOCATE_OBJECT:
- /*
- * SHADOW could not allocate a new object.
- */
- case CANNOT_ALLOCATE_PROCESS:
- /*
- * The method was supposed to invoke a process to
- * handle it, but failed to create the process.
- */
- case CANNOT_SEND_MESSAGE:
- /*
- * Either:
- * a) port is blocked.
- * b) no process to send to/from.
- * c) message could not be allocated.
- */
- case CANNOT_FIND_METHOD:
- /*
- * Could not find a method to send to!
- */
- default:
- }
- }
- }
-
-
- INPUTS
- <none>
-
- OUTPUTS
- double result; - low 32bits (d0) are the error, High
- 32bits (d1) are the error subcode.
- Be careful if your compiler starts
- checking for a double return in the
- 68881 processor, instead of d0/d1!!!
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- SetShadowError
-
- NAME
- GetTagsSize -- gets the size of a NULL terminated aray.
-
- SYNOPSIS
- size = GetTagsSize( tags, size )
- d0 a0 d0
-
- FUNCTION
- This function will find the size of a longword-NULL-terminated
- array. The NULL termination should be valid for the first longword
- of the last array element.
-
- The passed size should be the size of each array element.
-
-
- INPUTS
- void *tags; - a pointer to the array. If NULL, returns NULL
- long size; - the size of each element in the array.
-
- OUTPUTS
- long size; - the size of the array, including the NULL element.
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
-
- NAME
- InitOOProgram -- initialize an AmigaDOS process as a shadow process
-
- SYNOPSIS
- result = InitOOProgram( name )
- d0 a0
-
- FUNCTION
- This function will initialize the calling amigaDos process as
- a SHADOW process. This means that tc_UserData is HANDS OFF from
- that point on ('cept for read only). The process object is stored
- in tc_UserData and all message ports, etc. are allocated.
-
- This function MUST be called before initiating any non-CALL methods.
- Any methods that would require a SYNC or an ASYNC message
- require that a process object exist in tc_UserData of the calling
- task.
-
- If you want to use something other than PROCESS_CLASS, then you may
- first set FindTask(NULL)->tc_UserData to NULL, then call METH_SUB
- on the process class, then send that class a METH_CREATE, then
- send the object that that returns a METH_ASSOCIATE. That's all
- this function does.... [Excepting the METH_SUB call, of
- course....] Please be sure NOT to use the object that is returned
- (that is, do NOT DropObject() the returned process object!!!!)
-
- There is an example of this sans the mETH_SUB call in
- ShadowLibraryMethods.doc under the METH_PROC_ASSOCIATE method
- description.
-
-
-
- INPUTS
- char *name; - the name to give the process object.
-
- The name defaults to FindTask(NULL)->tc_Node.ln_Name when passed in
- as NULL.
-
- OUTPUTS
- BOOL result; - result code
-
- The result code is a boolean describing success or failure of process
- object creation.
-
- FALSE (0) is an error.
-
-
- RESULT
- Process object is created for the calling task.
-
- BUGS
- none known.
-
- NOTES
- tc_UserData is trashed (used)
-
- SEE ALSO
- RemoveCurrentProgram()
-
- NAME
- InitTable -- Initializes a memory table.
-
- SYNOPSIS
- result = InitTable( list, allocfunc, freefunc, size )
- d0 a0 a1 d0 d1
-
- FUNCTION
-
- Shadow requires a number of very small elements to be coninually
- allocated and freed. This function initializes a struct MemoryList
- which attempts to ease the strain on AllocMem and FreeMem by
- allocating and freeing blocks that are 32 times "size".
-
- The individual elements are allocated via the AllocateItem() and
- FreeItem() functions.
-
- InitTable initializes the various parts of the passed MemoryList
- structure.
-
-
- INPUTS
- SEMLIST list; - a MemoryList to initialize.
- TABLENODE allocfunc(SEMLIST); - an allocation function that, given a
- d0 a0 MemoryList, returns a MemoryNode
- structure as a header to 32
- elements to be doled out by
- AllocateItem(). If passed as NULL,
- the system uses an internal routine.
- void freefunc(SEMLIST, TABLENODE);
- a0 a1 - a free function that, given a
- MemoryList and a MemoryNode, frees
- the Node plus the 32 elements from
- the List. If passed as NULL, the
- system uses an internal routine.
- long size - the size of each element.
-
- OUTPUTS
- BOOL result; - result code
-
- The result code is a boolean indicating the success or failure of
- the function call. A zero value indicates that an error occured.
-
-
- RESULT
- The specified list is initilized, the first 32 elements are
- allocated, the semaphore is initialized, the memlst_semUse flag in
- the structure is set to TRUE, and the memlst_size set to the
- passed size.
-
- BUGS
- none known.
-
- NOTES
- It's not very flexible, but it's used for BinNodes, semaphores,
- list, and MethInvokeSpec internal structures. It's got pretty good,
- but not fantastic, performance. See "PerfTest MEMORY" results.
-
- SEE ALSO
-
- AllocateItem()
- FreeItem()
- FreeTable()
-
- NAME
- InitThread -- initializes the process object associated with the task.
-
- SYNOPSIS
- task = InitThread( task )
- d0 a0
-
- FUNCTION
- This function is no longer valid under SHADOW V. If you have been
- calling it and need directions on how to update your software,
- please see both the ShadowLibraryMethods.doc and the
- Introduction.doc about the PROCESS_CLASS.
-
- NOTES
- SUPERCEDED!
-
- NAME
- InsertSuperClass -- Take known class and insert another superclass level
-
- SYNOPSIS
- InsertSuperClass( subClass, newSuperClass )
- a0 a1
-
- FUNCTION
- This function is useful for adding methods to a Class. Unfortunately,
- it is currently impossible to remove these same methods once added,
- so be very careful with what you're doing here!
-
- Basically, this function takes the old superclass and makes the
- newSuperClass the old subclass' superclass. This function also
- flushes the entire method cache as it assumes that some method
- cache lines might be incorrect.
-
-
- INPUTS
- META subClass; - the subclass whose superclass will be changed.
- If NULL, no harm will come.
- META newSuperClass; - the new superClass for the passed subClass
- if NULL, the old superClass will remain.
-
- OUTPUTS
- <none>
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- The newSuperClass is "swallowed" by this function. if you want to
- keep the newSuperClass pointer valid within your sequence of
- execution after this call, you will need to do something like:
- InsertSuperClass(old, UseObject(new));
-
- This function is only valid if the new superclass is, itself, a
- subclass of the old subclass' superclass. IE:
- Class A
- |
- /\
- / \
- Class B Class C
- \
- \
- Class D
-
- It is valid to make Class B's new superclass either Class C or
- Class D. However, Class D cannot have its superclass reset to
- class B.
-
- No class may be its own superclass! Such a class would never go away!
-
- You may NOT add any new attributes with this call. That is, the
- newSuperClass must not have any new attributes not located in the
- oldSubClass. In addition, if you define default values for the
- existing attributes, these default attributes will NOT propagate
- down to the oldSubClass. This function is meant to add METHODS
- ONLY! Do not attempt to use it for anything else or you will be
- burnt.
-
-
- SEE ALSO
- UseObject()
- DropObject()
- CreateMeta()
-
- NAME
- InvalidateCache -- invalidates cache entries
-
- SYNOPSIS
- InvalidateCache( class, selector )
- a0
-
- FUNCTION
- This function will invalidate all entries in the method's cache that
- refer to the passed class and/or the passed selector.
-
- If passed a NULL class, then every entry in the cache that contains a
- selector field that matches the address of the passed selector is
- cleared. You should call this whenever you create a selector on the
- stack, or in memory, and then free the associated memory.
-
- If passed a NULL selector, then every entry in the cache that
- contains a class field that matches the address of passed class is
- cleared. You should call this whenever a class is free'd.
-
- if both fields are NULL, then the entire cache is flushed. This is
- called whenever a program exits from memory. That's because there
- are many methods which become invalid at that point, but
- invalidating all of them would be tedious, so the entire cache is
- flushed. Notice that that's with every PROGRAM, NOT every PROCESS.
-
- If both fields are passed in as non-NULL, then cache entries are
- only freed for those entries that match both the class and the
- selector. However, I haven't found a good use for this case.
- Perhaps you folks can?
-
-
- INPUTS
- META *class; - a class.
- char *selector; - a method selector
-
- OUTPUTS
-
-
- RESULT
- No more references to a defunct class exists in the method calling
- cache. No more references to the defunct selectors exists in the
- method calling cache.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DSM() DoShadow()
- SetMethodArgs()
- AddMethods()
- DestroyMethodTable()
- FindMethodHandle()
- BlockMethod()
- RemoveAllPatches()
- SetupMethodTags()
-
- NAME
- IpcItemTransfer -- Transfers a resource from message to server.
-
- SYNOPSIS
- IpcItemTransfer( msg, num )
- a0 d0
-
- FUNCTION
- This function will transfer the resource found in the num'th
- item in msg to the calling server.
-
- Basically, the IPC_ITEM_TRANSFER flag is cleared, and the
- IPC_SERVER_OWNED flag is set.
-
- This is very important to do when inside of a METH_DESTROY
- method. You need to transfer the passed object out of the message!
-
- INPUTS
- struct IPCMessage *msg; - the (possibly NULL) message to xfer
- resources from. If msg is NULL, no
- action is taken.
- long num; - the item number where the resource is
- currently located.
-
- OUTPUTS
- none
-
-
- RESULT
- resource is no longer valid in the message.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- IpcARGTransfer() macro
- ppipc.library documentation. Not included in SHADOW, but available
- on a Fred Fish disk.
-
- NAME
- JunkIPCMessage -- Frees a message allocated by MessageMaker
-
- SYNOPSIS
- JunkIPCMessage( msg )
- a0
-
- FUNCTION
- This function will delete an IPCMessage, releasing all resources
- which have not been IpcItemTransfer()'d.
-
- The message itself is also deleted.
-
- Message should have been allocated by MessageMaker, although that is
- not the only legal case, it is the safest route to compatibility.
- The PreParseShadow() function calls the MessageMaker() internally.
-
-
- INPUTS
- struct IPCMessage *msg; - the message to delete. If NULL, no action
- is taken.
-
- OUTPUTS
- none
-
-
- RESULT
- One more message is gone.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- MessageMaker()
- IpcItemTransfer()
-
- NAME
- MessageMaker -- Creates a Message for the given MethodHandle & args.
-
- SYNOPSIS
- msg = MessageMaker( handle, args )
- d0 a0 a1
-
- FUNCTION
- This function will create a ppipc message that MessageParse()
- and ParseShadowMessage() can unroll in order to call a method
- asynchronously across tasks.
-
- Full resource tracking is done, and all resources are freed
- during the JunkIPCMessage() call, unless an IpcItemTransfer()
- was performed for that resource's item.
-
- IpcItemTransfer should be done during METH_DESTROY.
-
-
- INPUTS
- struct MethodHandle *handle; - the method that the message should
- serve. Set the low bit of the
- address if this is actually a ptr
- into a MethodHandle object as
- returned from PatcherClass INIT.
- void **args; - the arguments that should be placed,
- one by one, into the message
- structure. Full resource
- tracking will be done for these
- arguments according to the
- ArgumentTag structure, so the message
- can be sent asynchronously.
-
- OUTPUTS
- struct IPCMessage *msg; - The returned message.
-
-
- RESULT
- A new message is constructed.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- JunkIPCMessage()
- DropObject()
- SetMethodArgs()
- ParseShadowMessage()
- MessageParse()
-
- NAME
- MessageParse -- Parses a message onto the stack.
-
- SYNOPSIS
- value = MessageParse( msg )
- d0 a0
-
- FUNCTION
- This function will parse a message onto the stack according to the
- ArgumentTag structure as passed inside of the message. The
- message must have exactly the right number of items, or bad
- things may happen.
-
- The Method is then called, and its return value returned in d0.
-
- There is also some magic which allows DSM() to be called as the
- function, so that methods which are forced ASYNC by the flags
- in an original DSM() call, actually work properly....
-
-
- INPUTS
- struct IPCMessage *msg; - should be a valid message set up by
- MessageMaker().
-
- OUTPUTS
- void *value; - the return value of the method call.
-
-
- RESULT
- The METHOD is called.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- MethodFuncParse()
- DSM()
- MessageMaker()
-
- NAME
- MethodFuncParse -- Copies the stack arguments back to the stack.
-
- SYNOPSIS
- return = MethodFuncParse( object, class, args, handle, flags )
- d0/d1 d0 d1 a1 a2 d7
-
- FUNCTION
- This function will copy the arguments found in args onto the stack,
- according to the ArgumentTag structure found in handle.
-
- Unlike MessageParse(), it must deal with missing arguments -- ie:
- it may encounter METHOD_END (0x80000001) before the end of the
- ArgumentTag argument array. The missing arguments are NULL'd out,
- then it calls the method function, and returns d0/d1 as a double.
-
- D0 is what should normally be considered as the return value.
- DSM() is incapable of returning real doubles at the current time.
- D1 is used by DSM() for its METH_FLAG_CHECK_CONTINUE.
- ParseShadowMessage() has some magic for storing D1 away for
- synchronous method calls.
-
- The 'msg' parameter of all Methods is NULL'd by MethodFuncParse().
-
-
- INPUTS
- OBJECT object; - the object being called.
- META *class; - the class the method is defined in.
- void **args; - the (other) arguments to the
- function.
- struct MethodHandler *handle;- the method's handle
- ULONG flags; - set this field to zero for now. This
- field reserved by system for future
- expansion and current asynchronous
- magic.
-
- OUTPUTS
- double return; - the return value is usually considered D0, but D1
- is used by DSM() for its _CONTINUE checking.
-
-
- RESULT
- The METHOD was called.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- MessageParse()
- DSM()
- ParseShadowMessage()
-
- NAME
- ParseShadowMessage -- parses the three types of SHADOW messages
-
- SYNOPSIS
- return = ParseShadowMessage( msg, flags )
- d0 a0 d0
-
- FUNCTION
- This function parses the three types of messages that SHADOW
- programs can receive -- AMET, SMET and JAZZ.
-
- AMET message are asynchronous messages, and these message are
- correctly handled by MessageParse(). The message is Junk()'d via
- the JunkIPCMessage call.
-
- SMET messages are synchronous message and these message are
- correctly handled by MethodFuncParse(). The message is
- replied to when MethodFuncParse() is finished.
-
- JAZZ messages are message you can send. The function pointer should
- be in the first element of the message, and the single argument to
- the function should be in the second argument. No value is
- currently returned -- but if someone needs to, please let me know.
- They are currently unused. The message is returned when the
- function is finished.
-
- The flags override certain features of this function. There
- are currently three flags:
- SHADOW_RETURN_MSG_ALWAYS
- SHADOW_RETURN_MSG_NEVER
- SHADOW_RETURN_MSG_ON_FAILURE
-
- By default (SHADOW_MSG_RETURN_NEVER), messages are always swallowed
- by this function. If you wish the message to neither be replied to
- or Junk()d via the JunkIPCMessage() call, call the function with the
- SHADOW_RETURN_MSG_ALWAYS. The msg will then be returned to you for
- whatver further processing you wish....
-
- If you don't know whether this is a SHADOW message or not, you can
- call the function with the SHADOW_RETURN_MSG_ON_FAILURE. If the
- message is not an AMET, SMET or JAZZ message, the msg will be
- returned to you for further processing. Note, however, that the
- assumption is that the message -is- a struct IPCMessage, and not
- some other form of message (like struct IntuiMessage, for instance).
- You have been warned.
-
- For the default behaviour, pass in the SHADOW_RETURN_MSG_NEVER
- flag. This was the old behaviour of ParseJazzMessage() under SHADOW
- 4.
-
- INPUTS
- struct IPCMessage *msg; - a message sent to a SHADOW task's port.
- ULONG flags; - one of three flags.
-
- OUTPUTS
- struct IPCMessage *return; - exact return is dependent on the flags
- passed into ParseShadowMessage().
-
-
- RESULT
- The correct function is called.
-
- BUGS
- Does not handle unknown messages without replyports properly under
- the SHADOW_RETURN_MSG_NEVER mode.
- So don't send them!
-
- NOTES
-
- SEE ALSO
- MessageParse()
- MethodFuncParse()
-
- NAME
- PrepareAttrTags -- Prepares Attribute tags for class definition
-
- SYNOPSIS
- num = PrepareAttrTags( tags, countptr, super )
- d0 a0 d1 a1
-
- FUNCTION
- This function is designed specifically because of the inherent
- trickiness of Metas.
-
- Under normal situations, the functionality of this function would be
- incorporated into AddAttributes(). Unfortunately, because Metas
- are their own classes, the size of the Meta depends on the
- definitions held in the defining AttributeTags. Therefore, the Meta
- cannot be allocated until it knows the required size, it wouldn't
- know the size until the AddAttributes call, but it can't call
- AddAttributes until the Meta exists so that the AttributeTable
- pointer can be passed in.
-
- At anyrate, this function determines the number of new attribute
- there are (returned num) and the additional size that will be
- needed (by incrementing the *countptr for each new attribute).
-
- Attributes which are already contained within the super are
- cheerfully ignored. Respecified Attributes are assumed to be
- attempts to redefine the default value, not to respecify an
- attribute's size.
-
- You probably won't need to use this function, unless you are
- creating your own Meta or METHODs for Metas.
-
-
- INPUTS
- ATTRIBUTE_TAG tags[]; - optional pointer to a NULL terminated
- array of AttributeTags.
- long *countptr; - initialized pointer to the long which
- will be incremented by the additional
- size required by the passed
- attributes. If any attributes are
- redefined (from the super), the size
- will not be incremented for that
- attribute.
- META *super; - optional pointer to a superclass.
-
- OUTPUTS
- long num; - number of new attributes (does not
- include attributes redefined from the
- passed super.
-
-
- RESULT
- The countptr variable is incremented by the additional size, above
- and beyond the size of 'super', that the passed attribute tags would
- require.
-
- BUGS
- none known.
-
- NOTES
- *countptr MUST be initialized, probably to the size of the
- superClass, as the size of the superClass is not used in calculating
- the size (*countPtr) in this function.
-
- SEE ALSO
- AddAttributes()
- CopyDefaultAttributes()
- FreeAttributes()
- FindAttribute()
- FindAttrDefn()
-
- NAME
- PSem -- procures the semaphore for the given address.
-
- SYNOPSIS
- result = PSem( address, flags )
- d0 a0 d0
-
- FUNCTION
-
- Copious documentation on the PSem() function is provided for in the
- Introduction.doc. Please see it if this AutoDoc does not answer
- your questions....
-
- This function semaphores the given address dictated by the
- following flags:
-
- SSEM_READ
- SSEM_ATTEMPT
- SSEM_WRITE
- SSEM_LOCK (SSEM_READ | SSEM_WRITE)
-
- In addition, several other flags alter the semaphoring code:
-
- SSEM_VARIABLE 0x8
- SSEM_MAX 0x10
- SSEM_SUBTRACT 0x80000000
- SSEM_DESTROY 0x20
-
-
- The following macros have been built around PSem() to add
- readability:
-
- /*
- * Conditional variables
- */
- SetCondition(address,number)\
- PSem(address, SSEM_VARIABLE | SSEM_READ | ((-number) << 8))
- WaitCondition(address,number)\
- PSem(address, SSEM_VARIABLE | SSEM_READ | (number << 8))
- CreateCondition() PSem((void *)-1, SSEM_VARIABLE)
- DestroyCondition(address)\
- PSem(address, SSEM_VARIABLE | SSEM_DESTROY)
-
- /*
- * Level-triggered semaphores.
- */
- WaitLevel(address)\
- PSem(address, SSEM_ATTEMPT|SSEM_WRITE);\
- PSem(address, SSEM_READ);\
- VSem(address)
- SetLevel(address)\
- VSem(address);
-
- /*
- * "Sticky" semaphores
- */
- CreateSemaphore(count) PSem((void *)-1, SSEM_MAX | (count << 8))
- DestroySemaphore(address) PSem(address, SSEM_DESTROY)
-
- /*
- * Couting semaphores of various kinds.
- */
- ObtainNumber(address,num) PSem(address, SSEM_READ | (num << 8))
- ReleaseNumber(address, num) PSem(address, SSEM_READ | ((-num) << 8))
- UpCountSem(address,max) PSem(address, SSEM_READ | SSEM_MAX |\
- (max << 8))
- DownCountSem(address) VSem(address)
-
- /*
- * Locks
- */
- WriteLock(address) PSem(address, SSEM_WRITE)
- ReadLock(address) PSem(address, SSEM_READ)
- RWLock(address) PSem(address, SSEM_READ | SSEM_WRITE)
-
-
- If anyone else attempts to semaphore the same address (via PSem),
- the system takes appropriate action (according to the flags).
-
- if the system cannot allocate a sempahore object internally,
- a busy loop with a Delay(30) is used until it can. You
- are guaranteed that, when PSem returns, you have a lock o
- the semaphore -- unless SSEM_ATTEMPT is used, in which case you must
- look at the return code.
-
-
- INPUTS
- void *address; - Any address within the system. (-1) is reserved
- as allocating a new semaphore -- that semaphore
- address would be returned....
- ULONG flags; - some combination of the flags above.
-
- OUTPUTS
- void *result; - result code for SSEM_ATTEMPT. Otherwise, returns
- semaphore address. This will be equivalent to
- the argument "address", or the allocated semaphore
- address if "address" is (-1).
- The result code for SSEM_ATTEMPT is (1L) for
- success and NULL for failure.
-
-
- RESULT
- The specified semaphore action will have taken place.
-
- BUGS
- none known.
-
- NOTES
-
- Although it is not strictly necessary, you will undoutedly encounter
- bugs if the address on which you have a semaphore is freed before the
- semaphore is. Mostly because another task may then allocate that
- address, and attempt a semaphore on it -- leading to unexpected
- deadly embrace conditions.
-
- The address passed need not point to an object, as the BinTree and
- List code require.
-
- SEE ALSO
- From exec.library:
- ObtainSemaphore()
- ObtainSemaphoreShared()
- AttemptSemaphore()
-
- VSem()
-
- Introduction.doc
-
- NAME
- PSemString -- used to ensure single-thread startup.
-
- SYNOPSIS
- result = PSemString( char *string, long semFlags )
- a0 d0
-
- FUNCTION
- Does the following:
- return PSem(UseString(string), semFlags);
-
- The browser uses this function to ensure that only a single
- copy of itself is running.
-
-
- INPUTS
- char *string; - the system string equivalent which is used to
- semaphore thread startup.
- long semFlags; - the flags to send to PSem().
-
- OUTPUTS
- void *result; - result code for SSEM_ATTEMPT. Otherwise, returns
- semaphore address. This will be equivalent to
- the argument "address", or the allocated semaphore
- address if "address" is (-1).
- The result code for SSEM_ATTEMPT is (1L) for
- success and NULL for failure.
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- VSemString()
- PSem()
- VSem()
-
- NAME
- QuickDropString -- Decrements the useCount of a known system string.
-
- SYNOPSIS
- QuickDropString( string )
- a2
-
- FUNCTION
- This function decrements the useCount of a known system string.
- The passed string *must* be a pointer to a system string.
-
- If the useCount drops to zero, DropString is automatically called
- in order to delete the string object from the correct place in
- the system's string hash table.
-
- Therefore, only call QuickDropString when you think you will have
- more than one reference to them. That allows QDS() to work
- fastest.
-
- INPUTS
- char *string; - the string to lower the refcounts of the system string.
-
- OUTPUTS
-
- RESULT
- The given system string has had its useCount decremented.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- UseString()
- QuickUseString()
- FindString()
- DropString()
-
- NAME
- QuickUseString -- Increment the usage counter of a system string.
-
- SYNOPSIS
- string = QuickUseString( string )
- d0 a2
-
- FUNCTION
- This function increments the system usage counter for a string
- that you already know is a system string. This must be the
- *address* of the system string, not a buffer pointer equivalent.
-
- If you pass in a NULL, this function returns a NULL.
-
- You should UseString() whenever saving a suitable string into
- a structure -- a matching DropString() will then deallocate the
- reference. Under the appropriate conditions (mentioned above)
- you may use QuickUseString() to avoid the hash and binary search
- calls.
-
-
- INPUTS
- char *string; - the system string whose useCount should be incremented
-
- OUTPUTS
- char *string; - the system string.
-
- Exactly what was passed into it!
-
-
- RESULT
- The system string's internal useCount is incremented
-
- BUGS
- none known.
-
- NOTES
- Don't pass in arbitrary buffer pointers or you may risk overwriting
- your stack, or memory.
-
- SEE ALSO
- UseString()
- FindString()
- DropString()
- QuickDropString()
-
- NAME
- RecurseTree -- Recursively call a function on each BinNode of an
- AVLTREE
-
- SYNOPSIS
- result = RecurseTree( bt, func, data, recurse )
- d0 a0 a1 d0 d1
-
- FUNCTION
- This function will recurse through the binary tree, calling func()
- for each object found with the parameters 'object key data', where
- object is the object in the binary tree, key is the key that the
- object is sorted on, and data is the data passed into the Recurse()
- call.
-
- If this func() ever returns non-NULL, the recursion is stopped, and
- the non_NULL return code is returned to the caller of RecurseTree.
-
- There are three different ways to recurse through a binary tree.
- The following flags are defined in shadow/bintree.h:
-
- SHADOW_RECURSE_INORDER == 1
- SHADOW_RECURSE_PREORDER == 2
- SHADOW_RECURSE_POSTORDER == 3
- SHADOW_RECURSE_BACKORDER == 4
-
- The order of the recursion is determined by these flags passed as
- the recurse parameter. INORDER outputs the left children, then the
- root, then the right children. PREORDER outputs the root, the left,
- then the right. POSTORDER outputs the left, the right, then the
- root. BACKORDER outputs the right, the root, then the left.
-
-
- INPUTS
- AVLTREE *bt; - the binary tree to recurse
- over.
- void *(*func)(void *, ULONG, void *) - the function. return value
- a0 d0 a1 used below. Return NULL to
- continue recursive calling,
- non-NULL to end recursive calls.
- Three parameters are:
- object, key, data.
- See above.
- void *data - the passed data
- long recurse - the recurse type flag.
-
- OUTPUTS
-
- void *result; - returns non-NULL result of func() if func() ever
- returns non-NULL. Else returns NULL.
-
- RESULT
- func() called for each element in the binary tree.
-
- BUGS
- None known.
-
- NOTES
- Do NOT RemoveTreeNode() the object from the binary tree that you
- are recursing through in the passed function. AND do not call any
- methods that would....
-
- Remember that the keys are sorted unsigned, not signed.
-
- SEE ALSO
- AddTreeNode() AddWatchedTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FindTreeNode() RemoveWatchedTreeNode()
- FreeTreeAllNodes() RemoveWatchedTreeStringNode()
- RemoveTreeNode()
- RemoveTreeStringNode()
-
- NAME
- RemoveAllPatches -- Removes all Patches from a given class.
-
- SYNOPSIS
- RemoveAllPatches( meta )
- a0
-
- FUNCTION
- This function will remove all of the method patches of a given
- class. This should be executed when deleting a class in which
- methods could be patched.
-
- It is currently called in the META_DESTROY of the metaclass and the
- metaCluster.
-
- Because of this, it is IMPOSSIBLE to patch the METH_DESTROY
- method for any metas, because they are their own classes -- the
- function that would call RemoveALlPatches may be in a method-chain,
- which would not be valid when control returned to DSM() to continue
- the method chain. This would be confusing, at best.... :(
-
-
- INPUTS
- META meta; - the class to delete all the patches from.
-
- OUTPUTS
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DSM() DoShadow()
- InvalidateCache()
- SetMethodArgs()
- AddMethods()
- DestroyMethodTable()
- FindMethodHandle()
- BlockMethod()
- SetupMethodTags()
-
- NAME
- RemoveAutoResource -- Removes resource from process' tracking tree.
-
- SYNOPSIS
- resource = RemoveAutoResource( task, resource, key )
- d0 a0 d0 a1
-
-
- FUNCTION
- The resource, which is found using the resource/key pair, is
- removed from the process' ATTR_RESOURCETREE and returned back
- to your control. No METH_REMOVE is done, and you must
- DropObject() the resource which is returned.
-
- Task parameter is optional and defaults to the current task.
- Resource parameter is optional, and defaults to whatever
- resource is found using the provided key. (If key >255, then
- key is assumed to be a string, and is handled accordingly.)
-
- INPUTS
- OBJECT task; - The optional task object that performs
- the auto-tracking. If not specified,
- assumes current taskObject.
- OBJECT resource; - The optional object being auto-tracked.
- If no resource, then resource is
- looked up on the binary tree using
- the value in key.
- char *key; - The name of the resource. Resources
- without names are stored by their
- addresses. Name addresses of 0-255
- are reserved for priority freeing.
- Resources are freed in INCREASING
- key order.
-
- OUTPUTS
- OBJECT resource; - The resource as found. You must
- DropObject() the returned resource
- when you are no longer interested in
- it. Eventually, you must
- RemoveObject() the resource when the
- resource is no longer needed
- -anywhere-!
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- AddAutoResource()
- DropObject()
-
- NAME
- RemoveClassWatcher -- Removes a watcher from all classes.
-
- SYNOPSIS
- RemoveClassWatcher( watchName, director, name, class )
- a0 a1 d0 d1
-
- FUNCTION
- This function will remove the director from the class' attribute
- watching SList of the passed name. This is a low-level routine.
- You should call the DIRECTOR_CLASS routines instead. See browser.c,
- or ShadowLibraryMethods.doc.
-
-
- INPUTS
- char *watchName; - the attribute name that is watched
- OBJECT director; - the director to Remove from the
- attribute watching SList.
- char *name; - the name of the watcher.
- META class; - the class to remove the watcher from.
-
- OUTPUTS
- none
-
- RESULT
- The director is removed from the class' watch list.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- AddWatcherNode()
- RemoveWatcherNode()
- AddClassWatcher()
-
- NAME
- RemoveCurrentProgram -- removes the current process from the system.
-
- SYNOPSIS
- RemoveCurrentProgram( semaphore )
- a0
-
- FUNCTION
- This function is the counterpart of InitOOProgram(). It removes an
- AmigaDOS loaded program from the system so that that program can exit
- safely.
-
- This is S.O.P. for cleaning up a -program-.
-
- RemoveCurrentProgram() waits for no other process to own a reference
- to the process associated with the program. While it does this, it
- handles messages on jp_port and jp_replyPort (struct ShadowProcess).
-
- This function sends a METH_REMOVE to the processObject, and waits on
- the process' jp_port and jp->replyPort for messages (which it manages
- by taking everything off the list, handling the messages, then
- checking for more signals). It also waits for a ^C and then checks
- that jp_parent is NULL.
-
- A program may create many threads on itself. When INIT'ing a process
- object, one parameter that the programmer can pass is a SEMF. This
- is a pointer to a semaphore that is passed into the process creation
- code. It is ObtainShared() during the process startup, and
- Release()'d when the thread is done executing.
-
- RemoveCurrentProgram() waits on this semaphore until all threads
- have exited before removing the program's process object.
-
- A NULL semaphore is dealt with appropriately.
-
-
- INPUTS
- struct SignalSemaphore *semaphore; - the thread semaphore
-
- OUTPUTS
-
-
- RESULT
- The program's process object is removed and associated ports freed.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- InitOOProgram()
-
- NAME
- RemoveObject -- send a METH_REMOVE to an object.
-
- SYNOPSIS
- RemoveObject( OBJECT object )
- a0
-
- FUNCTION
- Does a:
- DoShadow(object, NULL, METH_REMOVE, METHOD_END);
- Followed by a:
- DropObject(object);
-
- This removes the object from the system lists, and from your local
- sequence of execution. You should not refer to "object" after
- you pass it into this function unless you have maintained an
- additional usage of the object as in:
- RemoveObject(UseObject(object);
- /*
- * I can still use object!
- */
- .
- .
- .
- DropObject(object);
-
- INPUTS
- OBJECT object; - the object to send the Remove method to.
-
- OUTPUTS
- none.
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- CreateInstance() -- in ShadowLibFuncs.doc
- CreateSubClass() -- in ShadowLibFuncs.doc
-
- NAME
- RemoveSListNode -- removes a node from a prioritized, singly-linked
- list.
-
- SYNOPSIS
- result = RemoveSListNode( list, object, name )
- d0 a0 a1 d1
-
- FUNCTION
- This function removes an object from a singly linked list with the
- given name.
-
-
- INPUTS
- SList *list; - a pointer to the list from which to
- remove the object.
- OBJECT object; - the object to remove.
- char *name; - the name it was added as.
-
-
- OUTPUTS
- BOOL result; - result code
-
- returns FALSE if can't find the node to Remove.
-
-
- RESULT
- One fewer nodes are on the list.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- FindNodePriInSList() AddWatchedSListNode()
- AddSListNode() RemoveWatchedSListNode()
-
- NAME
- RemoveThread -- removes a previously initialized thread.
-
- SYNOPSIS
- RemoveThread( object )
- a0
-
- FUNCTION
- This function is no longer valid under SHADOW V. If you have been
- calling it and need directions on how to update your software,
- please see both the ShadowLibraryMethods.doc and the
- Introduction.doc about the PROCESS_CLASS.
-
- NAME
- RemoveTreeNode -- Removes a node from a binary tree
-
- SYNOPSIS
- result = RemoveTreeNode( bt, object, key )
- d0 a0 a1 d0
-
- FUNCTION
- This function will remove an object from the binary tree,
- dropping it via DropObject().
-
- The object pointer is required to verify the correct node is
- being removed (in case nodes with the same key exist in the
- same tree).
-
-
- INPUTS
- AVLTREE *bt; - a pointer to the root of the binary tree.
- OBJECT object; - the object to add into the tree.
- ULONG key; - the key value to insert on.
-
- OUTPUTS
- BOOL result
-
- returns FALSE on failure to remove.
-
-
- RESULT
- The object exists in the tree at least one fewer times than it did.
-
- BUGS
- none known.
-
- NOTES
- Remember that the keys are sorted unsigned, not signed.
-
- SEE ALSO
- DropObject()
-
- AddTreeNode() AddWatchedTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FindTreeNode() RemoveWatchedTreeNode()
- FreeTreeAllNodes() RemoveWatchedTreeStringNode()
- RecurseTree()
- RemoveTreeStringNode()
-
- NAME
- RemoveTreeStringNode -- Removes a node from a binary tree.
-
- SYNOPSIS
- result = RemoveTreeStringNode( bt, object, name )
- a0 a1 d1
-
- FUNCTION
- This function will remove an object from the binary tree,
- dropping it via DropObject(), and dropping the string
- via DropString (if the node is found!).
-
- The object pointer is required to verify that the correct node is
- being removed (in case nodes with the same key exist in the same
- tree).
-
-
- INPUTS
- AVLTREE *bt; - a pointer to the root of the binary tree.
- OBJECT object; - the object to add into the tree.
- char *name; - the name to insert on.
-
- OUTPUTS
- BOOL result
-
- returns FALSE on failure to remove.
-
-
- RESULT
- The object exists in the tree at least one fewer times than it did.
-
- BUGS
- none known.
-
- NOTES
- Yes, that's d1, not d0 for 'name' parameter.
-
- SEE ALSO
- DropObject DropString
-
- AddTreeNode() AddWatchedTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FindTreeNode() RemoveWatchedTreeNode()
- FreeTreeAllNodes() RemoveWatchedTreeStringNode()
- RecurseTree()
- RemoveTreeNode()
-
- NAME
- RemoveWatchedSListNode -- removes a node from a watched, prioritized
- singly-linked list.
-
- SYNOPSIS
- result = RemoveWatchedSListNode( list, object, name )
- d0 a0 a1 d1
-
- FUNCTION
- This function removes an object from a watched, singly-linked list
- with the given name.
-
- If any parties are interested, WatcherDispatch is called with
- W_REMOVE_NODE for the flag parameter.
-
-
- INPUTS
- W_SLIST list; - a pointer to the list from which to
- remove the object.
- OBJECT object; - the object to remove.
- char *name; - the name it was added as.
-
-
- OUTPUTS
- BOOL result; - result code
-
- returns FALSE if can't Remove.
-
-
- RESULT
- One fewer nodes are on the list.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- FindNodePriInSList() AddWatchedSListNode()
- AddSListNode()
- RemoveSListNode()
-
- NAME
- RemoveWatchedTreeNode -- Removes an object from the watched binary
- tree.
-
- SYNOPSIS
- result = RemoveWatchedTreeNode( bt, object, key )
- d0 a0 a1 d0
-
- FUNCTION
- This function will remove an object from the watched binary tree,
- dropping it via DropObject().
-
- The object pointer is required to verify the correct node is
- being removed (in case nodes with the same key exist in the
- same tree).
-
- If any parties are interested, WatcherDispatch is called with
- W_REMOVE_NODE
-
-
- INPUTS
- W_AVLTREE *bt; - a pointer to the root of the watched
- binary tree.
- OBJECT object; - the object to add into the tree.
- ULONG key; - the key value to insert on.
-
- OUTPUTS
- BOOL result
-
- returns FALSE on failure to Remove.
-
- RESULT
- The object exists in the tree at least one fewer times than it did.
-
- Remember that the keys are sorted unsigned, not signed.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DropObject()
-
- AddTreeNode() AddWatchedTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FindTreeNode()
- FreeTreeAllNodes() RemoveWatchedTreeStringNode()
- RecurseTree()
- RemoveTreeNode()
- RemoveTreeStringNode()
-
- NAME
- RemoveWatchedTreeStringNode -- Removes an object from the given
- binary tree
-
- SYNOPSIS
- result = RemoveWatchedTreeStringNode( bt, object, name )
- d0 a0 a1 d1
-
- FUNCTION
- This function will remove an object from the watched binary tree,
- dropping it via DropObject(), and dropping the string
- via DropString (if node is found!).
-
- The object pointer is required to verify the correct node is
- being removed (in case nodes with the same key exist in the
- same tree).
-
- If any parties are interested, WatcherDispatch is called with
- W_REMOVE_NODE
-
-
- INPUTS
- W_AVLTREE *bt; - a pointer to the root of the watched binary
- tree.
- OBJECT object; - the object to add into the tree.
- char *name; - the name to insert on.
-
- OUTPUTS
- BOOL result
-
- returns FALSE on failure to remove.
-
-
- RESULT
- The object exists in the tree at least one fewer times than it did.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DropObject DropString
-
- AddTreeNode() AddWatchedTreeNode()
- AddTreeStringNode() AddWatchedTreeStringNode()
- FindTreeNode() RemoveWatchedTreeNode()
- FreeTreeAllNodes()
- RecurseTree()
- RemoveTreeNode()
- RemoveTreeStringNode()
-
- NAME
- RemoveWatcherNode -- Removes a watcher to the watched variable
-
- SYNOPSIS
- result = RemoveWatcherNode( wv, node, name )
- a0 a1 d1
-
- FUNCTION
- This removes a watcher node from a watched variable. This
- is a low-level routine. You should call the DIRECTOR CLASS
- routines instead. See browser.c, or ShadowLibMethods.doc.
-
- If any parties are interested, WatcherDispatch is called with
- W_REMOVE_WATCHER for the flag parameter.
-
-
- INPUTS
- W_VALUE *wv; - the watched variable being watched.
- OBJECT node; - the director to remove from the watch
- list.
- char *name; - the name of the watcher.
-
- OUTPUTS
- BOOL result
-
- returns FALSE if failed to Remove.
-
-
- RESULT
- The director is removed from the watch list.
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- AddWatcherNode()
- AddClassWatcher()
- RemoveClassWatcher()
-
- NAME
- ReplaceObject -- Semaphored access to an object in a public area.
-
- SYNOPSIS
- oldObject = ReplaceObject(objectPtr ,newObject, oldValue )
- d0 a1 d0 d1
-
- FUNCTION
- In some attributes, there may be object pointers that you need
- to change in that attribute. On the other hand, somebody else
- might retrieve it at the same time.
-
- This function uses the ShadowBase->sb_semSemaphore to protect the
- access to the objectPtr. The object that is returned is returned
- Use()'d, so when you are done with the object you should call
- DropObject(object) on it. The old value that was stored at the
- objectPtr address is returned as oldObject and replaced by
- newObject if, and only if, it is the same as oldValue. Otherwise
- newObject is returned.
-
- The newObject is TRANSFERRED to the address, so if you want to
- maintain a valid pointer in newObject when ReplaceObject() returns,
- call this function like this:
-
- oldObject = ReplaceObject(objectPtr, UseObject(newObject), old);
-
- If you don't care about the returned object, you should call the
- function like this:
- DropObject(ReplaceObject(objectPtr, newObject, old));
-
- Note: the returned object may, in fact, be newObject, or oldValue --
- be sure you know what you're doing!
-
- INPUTS
- OBJECT *objectPtr; - the pointer to the structure element that
- holds the object pointer you want.
- OBJECT newObject; - object to transfer into the objectPtr.
- OBJECT oldValue; - the object value that this function will
- check for before replacing with newObject.
-
- OUTPUTS
- void *object; - either the same as oldValue or, newObject if
- *objectPtr doesn't point to oldValue.
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- GetObject()
- SetObject()
-
- NAME
- SetMethodArgs -- parses a ArgumentTag structure for method creation.
-
- SYNOPSIS
- SetMethodArgs( mh, args )
- a0 a1
-
- FUNCTION
- This is a system function, you should not need to call it.
- However, it does serve to elucidate several issues wrt ARGUMENT_TAG
- structures.
-
- This function parses out the ArgumentTag structure.
- It sets up the mh_num, mh_size and mh_args field in the
- passed MethodHandle structure.
-
- If the function returns a variable that needs to be kept
- track of, the last ArgumentTag structure (whose at_tag should be
- zero) in the array should contain information for async. method
- sends to safely deallocate or otherwise resource track the
- returned value.
-
- Valid returns are:
- SHADOW_RETURN_BLANK 0
- SHADOW_RETURN_OBJECT 1
- SHADOW_RETURN_STRING 2
- SHADOW_RETURN_PORT 3
- SHADOW_RETURN_TAGL 4
- SHADOW_RETURN_PTR 5
- SHADOW_RETURN_MRFO 6
-
- These values should be stored in the at_size field of the last
- ArgumentTag array item..
-
- For SHADOW_RETURN_PTR, the size of the pointer should be stored
- in the at_flags field of the same item, for SHADOW_RETURN_TAGL,
- the size of each array item should be stored in the at_flags field
- of this last item, and for SHADOW_RETURN_MRFO, the offset of the
- returned data from the object in question should be placed in the
- at_flags field
-
- Normally, the system supports a number of at_tag values:
- 'MRFO':
- used for object values which add at_flags to
- the passed object pointer.
- at_size should be four
- at_flags -- the offset of the passed data from the object ptr.
-
- Note that MRFO exists for system use, however you are free to
- use the item as well -- but it's of little to no use, just
- pass the object instead!
-
- 'JOBJ':
- Used for an object.
- at_size should be four
- at_flags should be one of:
- SHADOW_OBJECT
- SHADOW_CLASSLESSOBJECT
- SHADOW_META
- SHADOW_CLASS,
- SHADOW_CLUSTER
- SHADOW_COMPOSITE
- though this is more for peace of mind than necessity.
-
- 'JMSG':
- Used for a message creted by MessageMaker()
- at_size should be four
- at_flags should be zero
-
- 'JSTR':
- Used for a system string.
- at_size should be four
- at_flags should be zero
-
- 'PORT':
- Used for a ppipc port.
- at_size should be four
- at_flags should be ???? <-- anything you like!
-
- 'TAGL':
- Used for a NULL terminated array.
- at_size should be four.
- at_flags should be the size of each array item
-
- 'RTRN':
- reserved by the system, don't use.
- 'APTR'
- a pointer to some memory.
- at_size should be four.
- at_flags should be zero if you don't want to copy the data to
- another block when sending async., or should be the size of
- the data pointed to if you do.
-
- Create you own 4 character constant:
- at_size should be an even number -- you can pass arbitrarily
- large structures on the stack, this way.
- at_flags ignored.
-
-
- INPUTS
- struct MethodHandle *mh; - a MethodHandle being initialized.
- ARGUMENT_TAG args[]; - the (optional, and NULL-terminated)
- ArgumentTag array for this handle.
-
- OUTPUTS
-
-
- RESULT
- mh->mh_args, mh->mh_num, mh->mh_size fields are set up properly.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DSM() DoShadow()
- InvalidateCache()
- AddMethods()
- DestroyMethodTable()
- FindMethodHandle()
- BlockMethod()
- RemoveAllPatches()
- SetupMethodTags()
-
- NAME
- SetObject -- Semaphored access to an object in a public area.
-
- SYNOPSIS
- oldObject = SetObject(objectPtr , newObject )
- d0 a1 d1
-
- FUNCTION
- In some attributes, there may be object pointers that you need
- to change in that attribute. On the other hand, somebody else
- might retrieve it at the same time.
-
- This function uses the ShadowBase->sb_semSemaphore to protect the
- access to the objectPtr. The object that is returned is returned
- Use()'d, so when you are done with the object you should call
- DropObject(object) on it. The old value that was stored at the
- objectPtr address is returned as oldObject and replaced by
- newObject.
-
- The newObject is TRANSFERRED to the address, so if you want to
- maintain a valid pointer in newObject when SetObject() returns,
- call this function like this:
-
- oldObject = SetObject(objectPtr, UseObject(newObject));
-
- If you don't care about the returned object, you should call the
- function like this:
- DropObject(SetObject(objectPtr, newObject));
-
-
- INPUTS
- OBJECT *objectPtr; - the pointer to the structure element that
- holds the object pointer you want.
- OBJECT newObject; - object to transfer into the objectPtr.
-
- OUTPUTS
- void *object; - the object that *objectPtr points to.
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- GetObject()
- ReplaceObject();
-
- NAME
- SetShadowError -- Sets an error code for SHADOW
-
- SYNOPSIS
- SetShadowError(error, sub_error)
- d0 d1
-
- FUNCTION
- This function sets the last SHADOW error and suberror that
- occurred within the calling process' context to the passed values.
-
-
- INPUTS
- error ; - the error code to set.
- sub_error ; - the sub-error code to set.
-
- OUTPUTS
- <none>
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- GetShadowError
-
- NAME
- SetupMethodTags -- defines all methods in the MethodTag array as
- being run by a certain process object, and
- being owned by a certain object.
-
- SYNOPSIS
- SetupMethodTags( tags, procObject, defnObject )
- a1 d0 d1
-
- FUNCTION
- This function will initialize the (required, NULL-terminated) tags
- array so that each method is located in a particular defnObject and
- wants to be called in a partiular procObject's process.
-
- For instance, gui methods may exist in a libraryObject (ie: a
- library) and want to be run by the guiProcObject.
-
- If passed objects of -1, the current task object is used.
- [That is; FindTask(NULL)->tc_UserData -- CurrentProcess()]
-
- If any element within the METHOD_TAG has a defnObject already set
- (non-NULL), then the defnObject for that element remains as before.
- Similarly for the procObject field.
-
-
- INPUTS
- METHOD_TAG tags[]; - NULL-terminated MethodTag array.
- OBJECT procObject; - the process object in which to run
- the methods.
- OBJECT defnObject; - the object that "contains" the
- definition of the ArgumentTag -and-
- the function code.
-
- OUTPUTS
-
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
- This is what guarantees that the function and ArgumentTag pointers
- remain valid as long as a method could call that function.
- The ArgumentTag structure is NOT copied when stored into the
- MethodHandler structure (the information in MethodTags and
- AttributeTags is).
-
- This function does not produce valid results for methods that are
- defined as METH_FLAG_CLASS or METH_FLAG_PORT or METH_FLAG_SPEC.
- You will have to fill in the procObject field for these
- method-types yourself.
-
- SetupMethodTags() only affects procObject and defnObject fields
- that are NULL.
-
- SEE ALSO
- DSM() DoShadow()
- InvalidateCache()
- SetMethodArgs()
- AddMethods()
- DestroyMethodTable()
- FindMethodHandle()
- BlockMethod()
- RemoveAllPatches()
-
- NAME
- UseObject -- resource tracking for shadow objects.
-
- SYNOPSIS
- object = UseObject( object )
- d0 a0
-
- FUNCTION
- This function increments the object's cob_useCount field.
- You should Use an object whenever you save a pointer into
- a structure.
-
-
- INPUTS
- OBJECT object; - the object to effect the change upon.
- If NULL, nothing happens
-
- OUTPUTS
- OBJECT object; - the same as the object sent in.
-
-
- RESULT
- object's cob_object is incremented.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- DropObject()
-
- NAME
- UseString -- gets a system-wide address for a given string.
-
- SYNOPSIS
- string = UseString( buffer )
- d0 a2
-
- FUNCTION
- Shadow uses a system very much similar to the NeXT's -- a system-
- wide repository for statis-string addresses.
-
- Strings are hashed into a 1024 table entry and chained onto sorted
- binary trees. The string which is returned is guaranteed to be a
- unique string address for the passed buffer.
-
- The passed buffer's address is *NOT* used as the system string
- address, so it can be a temporary stack-allocated buffer. The
- system string is created when a first UseString() is called for
- a given buffer. On the second UseString() call for the same buffer,
- the same string address will be returned, and an internal counter
- which tracks the string usage is incremented.
-
- These system strings may *NOT* be mangled, they are read-only.
- They are particularly good for static data that you wish to do
- searches on, as system-strings have a unique address, strcmp() is
- unnecessary, merely compare the string addresses. They are used
- internally for BinNode strings, method names, attribute names,
- class names, etc.
-
-
- INPUTS
- char *buffer; - the string to retrieve a unique system pointer for.
- Given a NULL input, will return NULL.
-
- OUTPUTS
- char *string; - the unique string as returned by the system. A NULL
- signals an error.
-
-
- RESULT
- Either a new system string is created, and the buffer copied into
- it, or an old system string is retrieved and its usage counter
- incremented.
-
- BUGS
- none known.
-
- NOTES
- The buffer should be word-aligned for faster access and long-word
- aligned for fastest access.
-
- SEE ALSO
- QuickUseString()
- FindString()
- DropString()
- QuickDropString()
-
- NAME
- VSem -- Vacate a semaphore
-
- SYNOPSIS
- VSem( address )
- a0
-
- FUNCTION
- This function does the equivalent of a ReleaseSemaphore on the
- given address.
-
- Every PSem() should be matched with a VSem(), except for PSem()s
- where an SSEM_ATTEMPT failed (returned NULL, in which case VSem()
- should NOT be called.
-
-
- INPUTS
- void *address; - Any address in the system.
-
- OUTPUTS
-
-
- RESULT
- The semaphore will be released (vacated), and the semaphore object
- freed if no longer needed.
-
- BUGS
- none known.
-
- NOTES
- If no semaphore with that address can be found, nothing happens.
- But this case may a bug in the user program as you shoudn't
- be freeing semaphores no one has allocated....
-
- SEE ALSO
- From exec.library:
- ReleaseSemaphore()
-
- PSem()
- Introduction.doc
-
- NAME
- VSemString -- used to ensure single-threaded startup.
-
- SYNOPSIS
- VSemString( char *string )
- a0
-
- FUNCTION
- Does the following:
- VSem(FindString(string), semFlags);
- DropString(string);
-
- The browser uses this function to ensure that only a single
- copy of itself is running.
-
-
- INPUTS
- char *string; - the system string equivalent which is used to
- semaphore thread startup.
-
- OUTPUTS
- none.
-
- RESULT
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- PSemString()
- PSem()
- VSem()
-
- NAME
- WaitThread -- synchronizes thread startup.
-
- SYNOPSIS
- task = WaitThread( )
- d0
-
- FUNCTION
- This function is no longer valid under SHADOW V. If you have been
- calling it and need directions on how to update your software,
- please see both the ShadowLibraryMethods.doc and the
- Introduction.doc about the PROCESS_CLASS.
-
- NAME
- WatcherDispatch -- Dispatches all notification methods.
-
- SYNOPSIS
- WatcherDispatch( flag, wv, first, second )
- d0 a0 a1 d1
-
- FUNCTION
- This function dispatches notification to all parties that
- have added themselves either to the WatchedVariable in
- question, or to the SList that wv->wv_firstClass points to.
-
- Watched Values are a tricky subject which will require a lot
- more than a simple AutoDoc note to explain them.
-
- Please see examples in browser.c for now, or refer to the
- DIRECTOR_CLASS documentation in ShadowLibMethods.doc and
- Introduction.doc.
-
-
- INPUTS
- long flag; - Informs of the type of change made to the value:
- W_CHANGE_ZERO 1
- W_CHANGE_NON_ZERO 2
- W_INSERT_WATCHER 40
- W_REMOVE_WATCHER 24
- W_INSERT_NODE 32
- W_REMOVE_NODE 16
- W_VALUE *wv; - the watchedValue that was changed.
- void *first; - the object that was added to the list/AVLTREE, or
- the value that the variable was changed to.
- void *second; - the name or key for the new node in the list/AVLTREE
-
- OUTPUTS
-
-
- RESULT
- All interested parties are informed of the change.
-
- BUGS
- none known.
-
- NOTES
-
- SEE ALSO
- AddWatcherNode()
- AddClassWatcher()
-